我可以在另一个INSERT中使用INSERT ... RETURNING的返回值吗?

时间:2011-07-03 00:52:45

标签: postgresql sql-returning

这样的事情可能吗?

INSERT INTO Table2 (val)
VALUES ((INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id));

比如使用返回值作为值来在第二个表中插入一行并引用第一个表?

6 个答案:

答案 0 :(得分:75)

您可以从Postgres 9.1开始:

with rows as (
INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id
)
INSERT INTO Table2 (val)
SELECT id
FROM rows

同时,如果您只对id感兴趣,可以使用触发器来执行此操作:

create function t1_ins_into_t2()
  returns trigger
as $$
begin
  insert into table2 (val) values (new.id);
  return new;
end;
$$ language plpgsql;

create trigger t1_ins_into_t2
  after insert on table1
for each row
execute procedure t1_ins_into_t2();

答案 1 :(得分:46)

这种情况的最佳做法。使用RETURNING … INTO

INSERT INTO teams VALUES (...) RETURNING id INTO last_id;

答案 2 :(得分:8)

符合Denis de Bernardy给出的答案。

如果您希望之后返回id,并希望在Table2中插入更多内容:

with rows as (
INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id
)
INSERT INTO Table2 (val, val2, val3)
SELECT id, 'val2value', 'val3value'
FROM rows
RETURNING val

答案 3 :(得分:7)

您可以使用lastval()功能:

  

对于任何序列

,使用nextval最近获得的返回值

这样的事情:

INSERT INTO Table1 (name) VALUES ('a_title');
INSERT INTO Table2 (val)  VALUES (lastval());

只要没有人在您的INSERT之间的任何其他序列(在当前会话中)调用nextval(),这将正常工作。

正如下面提到的Denis并且我在上面警告过,如果在INSERT之间使用lastval()访问另一个序列,使用nextval()会让您遇到麻烦。如果Table1上的INSERT触发器在序列上手动调用nextval(),或者更有可能在具有SERIAL or BIGSERIAL主键的表上执行INSERT,则可能会发生这种情况。如果你想变得非常偏执(一件好事,他们真的是你终究得到你了),那么你可以使用currval(),但你需要知道它的名字。相关序列:

INSERT INTO Table1 (name) VALUES ('a_title');
INSERT INTO Table2 (val)  VALUES (currval('Table1_id_seq'::regclass));

自动生成的序列通常名为t_c_seq,其中t是表名,c是列名,但您始终可以通过进入psql来查找话说:

=> \d table_name;

然后查看相关列的默认值,例如:

id | integer | not null default nextval('people_id_seq'::regclass)

仅供参考:lastval()或多或少是MySQL的LAST_INSERT_ID的PostgreSQL版本。我只提到这一点,因为很多人比PostgreSQL更熟悉MySQL,所以将lastval()链接到熟悉的东西可能会澄清事情。

答案 4 :(得分:2)

DO $$
DECLARE tableId integer;
BEGIN
  INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id INTO tableId;
  INSERT INTO Table2 (val) VALUES (tableId);
END $$;

使用psql(10.3,服务器9.6.8)进行测试

答案 5 :(得分:0)

  

table_ex

     

id default nextval(' table_id_seq' :: regclass),

     

camp1 varchar

     

camp2 varchar

INSERT INTO table_ex(camp1,camp2) VALUES ('xxx','123') RETURNING id