我可以在另一个INSERT中使用INSERT … RETURNING的返回值吗?
是这样的可能吗?
INSERT INTO Table2 (val) VALUES ((INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id));
比如使用返回值作为值在第二个表中插入一行并引用第一个表?
你可以从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();
这种情况的最佳做法。 使用RETURNING … INTO
。
INSERT INTO teams VALUES (...) RETURNING id INTO last_id;
你可以使用lastval()
函数:
返回最近用
nextval
获得的任何序列的值
所以像这样的东西:
INSERT INTO Table1 (name) VALUES ('a_title'); INSERT INTO Table2 (val) VALUES (lastval());
只要没有人在INSERT之间的任何其他序列(在当前会话中)调用nextval()
,这将工作正常。
正如Denis在下面指出的,我在上面提到过,如果在INSERT之间使用nextval()
访问另一个序列,则使用lastval()
可能会导致麻烦。 如果在Table1
上有INSERT触发器在序列上手动调用nextval()
,或者更可能是在具有SERIAL
或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()
或多或less是MySQL的LAST_INSERT_ID
的PostgreSQL版本。 我只提到这一点,因为很多人比PostgreSQL更熟悉MySQL,所以把lastval()
和熟悉的东西联系起来可能会澄清一些事情。
根据丹尼斯·德·伯纳迪给出的答案。
如果你希望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
table_ex
id default nextval('table_id_seq':: regclass),
camp1 varchar
camp2 varchar
INSERT INTO table_ex(camp1,camp2) VALUES ('xxx','123') RETURNING id