我可以在另一个 INSERT 中使用 INSERT...RETURNING 的返回值吗?
这样的事情可能吗?
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以从 Postgres 9.1 开始执行此操作:
同时,如果您只对 id 感兴趣,则可以使用触发器执行此操作:
You can do so starting with Postgres 9.1:
In the meanwhile, if you're only interested in the id, you can do so with a trigger:
针对这种情况的最佳实践。使用
返回…进入
。请注意,这是针对 PLPGSQL 的
The best practice for this situation. Use
RETURNING … INTO
.Note this is for PLPGSQL
使用 psql 进行测试(10.3,服务器 9.6.8)
Tested with psql (10.3, server 9.6.8)
与 Denis de Bernardy 给出的答案一致。
如果您希望之后也返回 id 并希望在 Table2 中插入更多内容:
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:
您可以使用
lastval()
功能:所以像这样:
只要没有人对任何其他序列(在当前的序列中)调用
nextval()
,这就可以正常工作会话)在您的 INSERT 之间。正如 Denis 在下面指出的以及我在上面警告的那样,使用
lastval()
会给你带来麻烦如果在 INSERT 之间使用nextval()
访问另一个序列。如果Table1
上有一个 INSERT 触发器,在序列上手动调用nextval()
,或者更可能的是,在带有SERIAL
或BIGSERIAL
主键。如果你真的想变得偏执(这是一件好事,毕竟他们真的是你来抓你的),那么你可以使用currval()
但您需要知道相关序列的名称:自动生成的序列是通常命名为
t_c_seq
其中t
是表名称,c
是列名称,但您始终可以通过进入psql
找到答案> 并说:然后查看相关列的默认值,例如:
仅供参考:
lastval()
或多或少是 MySQLLAST_INSERT_ID
。我之所以提到这一点,是因为很多人比 PostgreSQL 更熟悉 MySQL,因此将lastval()
链接到熟悉的东西可能会澄清一些事情。You can use the
lastval()
function:So something like this:
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 usingnextval()
between your INSERTs. This could happen if there was an INSERT trigger onTable1
that manually callednextval()
on a sequence or, more likely, did an INSERT on a table with aSERIAL
orBIGSERIAL
primary key. If you want to be really paranoid (a good thing, they really are you to get you after all), then you could usecurrval()
but you'd need to know the name of the relevant sequence:The automatically generated sequence is usually named
t_c_seq
wheret
is the table name andc
is the column name but you can always find out by going intopsql
and saying:and then looking at the default value for the column in question, for example:
FYI:
lastval()
is, more or less, the PostgreSQL version of MySQL'sLAST_INSERT_ID
. I only mention this because a lot of people are more familiar with MySQL than PostgreSQL so linkinglastval()
to something familiar might clarify things.