【问题标题】:How to use the RETURNING clause to insert into two tables? [duplicate]如何使用 RETURNING 子句插入两个表? [复制]
【发布时间】:2020-05-23 17:40:08
【问题描述】:

我不明白如何使用RETURNING,例如如何获得“在我手中”的实际价值以进行下一步。假设,我有两张桌子:

create table "actors" (
  id_act serial not null primary key,
  first_name text not null,
  last_name text not null
);
create table movies (
  id_mov serial not null primary key,
  act_id integer not null
);

现在我添加一个演员:

INSERT INTO actors (first_name, last_name) VALUES ('Tom', 'Hanks');

紧接着,我想用那个新演员的 ID 插入一部电影:

INSERT INTO movies(###);

如何使用RETURNING 代替占位符###?

【问题讨论】:

    标签: sql postgresql sql-returning


    【解决方案1】:

    你不需要 PL/pgSQL 来使用RETURNING,这也可以在普通 SQL 中使用。

    但是对于您遇到的问题,您不需要,因为您可以使用来自支持actors.id 的序列中的currval() 来获取最后生成的id

    INSERT INTO actors (first_name, last_name) VALUES ('Tom', 'Hanks');
    INSERT INTO movies(act_id) values 
    (currval(pg_get_serial_sequence('actors', 'act_id')));
    

    如果你真的想使用 RETURNING,你可以使用data modifying CTE

    with new_actor as (
      INSERT INTO actors (first_name, last_name) VALUES ('Tom', 'Hanks')
      returning id_act
    )
    insert into movies (act_id)
    select id_Act
    from new_actor;
    

    Online example

    【讨论】:

    • 谢谢,但是...我发出了五次 INSERT INTO 演员 (first_name, last_name) VALUES ('Tom', 'Hanks'); id_act now is = 5 之后我发出 INSERT INTO movies(act_id) values (lastval());并假设将 5 视为 act_id,但它始终是 Movies 的最高 ID,而不是 Actors 的最新 ID
    • with .. 版本产生 SQL 错误:返回 id;在“;”处或附近
    • @StOMicha:我在 CTE 中输入了错误的 ;。你是对的lastval() 不起作用,因为movies 也有一个串行列。查看我的编辑
    • 非常感谢,新的...看起来不错有什么办法可以将该 ID 放入变量中以供其他用途?
    【解决方案2】:

    您需要在 INSERT 语句中使用 RETURNING 子句将返回值存储在另一个变量中。

    例子:

    create or replace procedure insert_rows()
    language plpgsql
    as
    $$
    declare
     v_id_act int;
    begin
    INSERT INTO actors (first_name, last_name) VALUES ('Tom', 'Hanks') RETURNING id_act INTO v_id_act;
    INSERT INTO movies(act_id) values (v_id_act);
    end;
    $$;
    CREATE PROCEDURE
    
    call insert_rows();
    CALL
    
    select * from actors;
     id_act | first_name | last_name 
    --------+------------+-----------
          1 | Tom        | Hanks
    (1 row)
    
    select * from movies;
     id_mov | act_id 
    --------+--------
          1 |      1
    (1 row)
    

    【讨论】:

    • 谢谢,但是...我发出了上面的CREATES,声明v_id_act int;插入演员 (first_name, last_name) 值 ('Tom', 'Hanks') RETURNING id_act INTO v_id_act;这会导致 SQL-Error [42601]: ERROR: syntax error at or near "INTO"
    • 我已经用psql显示了语句执行的输出:你只需要在psql中运行create or replace ... $$;(11行)一次性。我不明白你怎么会有语法错误。您使用哪个工具来运行语句?
    • 我使用了dBeaver。我不想要这个程序;这里 [link] (postgresqltutorial.com/postgresql-insert) 我找到了一个描述,请参考上一章“获取最后一个插入 id”:我现在想要的只是将那个值“8”拿到我手中,以便进一步存储和使用。
    • 您的主机编程语言是什么?也许可以使用主机变量进行检索,但我不确定。如果这是您真正想要做的,请提出一个详细说明此特定需求的新问题,并将宿主语言添加为问题标签。
    猜你喜欢
    • 1970-01-01
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多