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

这种事有可能吗?

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

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

151390 次浏览

你可以使用 lastval()函数:

返回最近用 nextval获得的任何序列的值

So something like this:

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

只要没有人对 INSERT 之间的任何其他序列(在当前会话中)调用 nextval(),这就可以很好地工作。

正如下面提到的 丹尼斯和我上面警告的那样,如果在 INSERT 之间使用 nextval()访问另一个序列,那么使用 lastval()可能会给您带来麻烦。如果 Table1上有一个 INSERT 触发器,它对序列手动调用 nextval(),或者更有可能对具有 ABC4或 BIGSERIAL主键的表执行 INSERT,则可能发生这种情况。如果你真的想成为一个偏执狂(一件好事,他们真的是你得到你毕竟) ,那么你可以使用 nextval()0,但你需要知道相关序列的名称:

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()链接到熟悉的东西可能会澄清一些事情。

你可以从 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;

注意,这是针对 PLPGSQL 的

Table _ ex

Id 缺省 nextval (‘ table _ id _ seq’: : regclass) ,

Camp1 Varchar

Camp2 Varchar

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

根据 Denis de Bernardy 给出的答案. 。

如果您希望随后也返回 id,并希望在表2中插入更多内容:

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
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)进行测试