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

发布于 2024-11-18 03:08:39 字数 176 浏览 3 评论 0原文

这样的事情可能吗?

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

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

Is something like this possible?

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

like using the return value as value to insert a row in a second table with a reference to the first table?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

我三岁 2024-11-25 03:08:39

您可以从 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();

You can do so starting with Postgres 9.1:

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

In the meanwhile, if you're only interested in the id, you can do so with a trigger:

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();
旧话新听 2024-11-25 03:08:39

针对这种情况的最佳实践。使用返回…进入

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

请注意,这是针对 PLPGSQL 的

The best practice for this situation. Use RETURNING … INTO.

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

Note this is for PLPGSQL

明月松间行 2024-11-25 03:08:39
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)

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

Tested with psql (10.3, server 9.6.8)

花开半夏魅人心 2024-11-25 03:08:39

与 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

In line with the answer given by Denis de Bernardy..

If you want id to be returned afterwards as well and want to insert more things into 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
百善笑为先 2024-11-25 03:08:39

您可以使用 lastval() 功能:

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

所以像这样:

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

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

正如 Denis 在下面指出的以及我在上面警告的那样,使用 lastval() 会给你带来麻烦如果在 INSERT 之间使用 nextval() 访问另一个序列。如果 Table1 上有一个 INSERT 触发器,在序列上手动调用 nextval(),或者更可能的是,在带有 SERIALBIGSERIAL 主键。如果你真的想变得偏执(这是一件好事,毕竟他们真的是你来抓你的),那么你可以使用 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 更熟悉 MySQL,因此将 lastval() 链接到熟悉的东西可能会澄清一些事情。

You can use the lastval() function:

Return value most recently obtained with nextval for any sequence

So something like this:

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

This will work fine as long as no one calls nextval() on any other sequence (in the current session) between your INSERTs.

As Denis noted below and I warned about above, using lastval() can get you into trouble if another sequence is accessed using nextval() between your INSERTs. This could happen if there was an INSERT trigger on Table1 that manually called nextval() on a sequence or, more likely, did an INSERT on a table with a SERIAL or BIGSERIAL primary key. If you want to be really paranoid (a good thing, they really are you to get you after all), then you could use currval() but you'd need to know the name of the relevant sequence:

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

The automatically generated sequence is usually named t_c_seq where t is the table name and c is the column name but you can always find out by going into psql and saying:

=> \d table_name;

and then looking at the default value for the column in question, for example:

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

FYI: lastval() is, more or less, the PostgreSQL version of MySQL's LAST_INSERT_ID. I only mention this because a lot of people are more familiar with MySQL than PostgreSQL so linking lastval() to something familiar might clarify things.

小伙你站住 2024-11-25 03:08:39

表_ex

id 默认 nextval('table_id_seq'::regclass),

camp1 varchar

camp2 varchar

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

table_ex

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

camp1 varchar

camp2 varchar

INSERT INTO table_ex(camp1,camp2) VALUES ('xxx','123') RETURNING id 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文