通过一个可更新的视图从INSERTED记录中返回一列。

问题描述 投票:0回答:1

我有一个视图,我需要允许我的用户更新和插入。重要的是,当他们插入时,他们需要能够从插入的行返回新的值,然而现在他们得到的是NULL。它必须是一个视图,因为在视图的SELECT中,它需要能够返回的值是连接的结果。

我的底层表定义。

CREATE TABLE my_assets (
    asset_id bigserial not null primary key,
    asset_price NUMERIC(32,10) -- This will vary constantly via an independent process
);

CREATE TABLE my_transactions (
    id bigserial not null primary key,
    asset_id bigint not null REFERENCES my_assets(asset_id),
    some_text varchar(100)
);
INSERT INTO my_assets(asset_price) SELECT 100 as asset_price;

我的视图,显示表的结果。

CREATE VIEW my_transactions_view AS
SELECT tx.id, tx.asset_id, tx.some_text, a.asset_price
FROM my_transactions tx
JOIN my_assets a ON tx.asset_id = a.asset_id

我的触发器,允许插入到 my_transactions_view:

CREATE OR REPLACE FUNCTION trigfx_insert_to_my_transactions_view()
RETURNS trigger AS
    $BODY$
BEGIN
    INSERT INTO my_transactions(asset_id, some_text)
    SELECT NEW.asset_id, NEW.some_text;
    RETURN NEW;
END
    $BODY$
    LANGUAGE 'plpgsql';

CREATE TRIGGER trig_my_transactions_view INSTEAD OF INSERT on my_transactions_view
FOR EACH ROW EXECUTE PROCEDURE trigfx_insert_to_my_transactions_view();

到目前为止一切正常。但是,在尝试运行以下SQL语句时出现了问题。

INSERT INTO my_transactions_view(asset_id, some_text)
    SELECT 1 as asset_id, 'Hello World' as some_text
    RETURNING id, asset_id, some_text;

返回的表ID为NULL但我想从该函数中返回新更新的ID。my_transactions 表。

|---------------------|------------------|------------------|
|         ID          |     asset_id     |    some_text     |
|---------------------|------------------|------------------|
|        null         |         1        |  Hello World     |
|---------------------|------------------|------------------|

运行后续 SELECT * FROM my_transactions_view 确实产生了更新的结果,但我需要在返回INSERT语句时产生。

|------------------|------------------|------------------|------------------|
|         ID       |     asset_id     |    some_text     |    asset_price   |
|------------------|------------------|------------------|------------------|
|         1        |         1        |  Hello World     |  100.0000000     |
|------------------|------------------|------------------|------------------|

但我需要在INSERT语句的返回过程中产生结果。

sql postgresql triggers database-trigger hasura
1个回答
1
投票

你可以填充 new 的记录。

CREATE OR REPLACE FUNCTION trigfx_insert_to_my_transactions_view()
RETURNS trigger AS
    $BODY$
BEGIN
    INSERT INTO my_transactions(asset_id, some_text)
    values (NEW.asset_id, NEW.some_text);
    new.id := lastval(); --<< this gets the generated id from the transactions table
    RETURN NEW;
END
$BODY$
LANGUAGE plpgsql;

在线示例

或者您可以使用 currval(pg_get_serial_sequence('my_transactions','id')) 而不是 lastval()


0
投票

原来我们可以通过CTE中的SELECT INTO来避免额外的函数调用。

CREATE OR REPLACE FUNCTION trigfx_insert_to_my_transactions_view()
RETURNS trigger AS
    $BODY$
BEGIN
    WITH ins_q as (INSERT INTO my_transactions(asset_id, some_text)
    values (NEW.asset_id, NEW.some_text)
    RETURNING id, asset_id, some_text)
    SELECT ins_q.id, ins_q.asset_id, ins_q.some_text
    INTO NEW.id, NEW.asset_id, NEW.some_text
    FROM ins_q;
    RETURN NEW;
END
$BODY$
LANGUAGE plpgsql;

请看这里的在线示例。我遇到了初始化错误(lastval is not yet defined in this session)与 new.id := lastval(); 办法。

© www.soinside.com 2019 - 2024. All rights reserved.