postgresql:嵌套插入
我有两张桌子。让我们说 tblA 和 tblB。
我需要在 tblA 中插入一行,并使用返回的 id 作为要插入到 tblB 中的列之一的值。
我尝试在文档中找到这一点,但无法得到它。 那样编写一条语句(旨在在准备中使用)
INSERT INTO tblB VALUES
(DEFAULT, (INSERT INTO tblA (DEFAULT, 'x') RETURNING id), 'y')
那么,是否可以像我们为 SELECT 所做的
?或者我应该通过创建存储过程来做到这一点?我不确定是否可以从存储过程中创建准备好的语句。
请指教。
问候,
玛雅克
I have two tables. Lets say tblA and tblB.
I need to insert a row in tblA and use the returned id as a value to be inserted as one of the columns in tblB.
I tried finding out this in documentation but could not get it. Well, is it possible to write a statement (intended to be used in prepared) like
INSERT INTO tblB VALUES
(DEFAULT, (INSERT INTO tblA (DEFAULT, 'x') RETURNING id), 'y')
like we do for SELECT?
Or should I do this by creating a Stored Procedure?. I'm not sure if I can create a prepared statement out of a Stored Procedure.
Please advise.
Regards,
Mayank
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
为此,您需要等待 PostgreSQL 9.1:
同时,您需要在应用程序中使用 plpgsql、临时表或一些额外的逻辑...
You'll need to wait for PostgreSQL 9.1 for this:
In the meanwhile, you need to use plpgsql, a temporary table, or some extra logic in your app...
这在 9.0 和用于匿名块的新
DO
中是可能的:这可以作为单个语句执行。我还没有尝试从中创建一个PreparedStatement。
编辑
另一种方法是简单地分两步进行,首先使用returning子句运行插入到tableA中,通过JDBC获取生成的值,然后触发第二次插入,如下所示:
This is possible with 9.0 and the new
DO
for anonymous blocks:This can be executed as a single statement. I haven't tried creating a PreparedStatement out of that though.
Edit
Another approach would be to simply do it in two steps, first run the insert into tableA using the returning clause, get the generated value through JDBC, then fire the second insert, something like this:
您可以在两次插入中执行此操作,使用
currval()
检索外键(前提是键是serial):结果:
以这种方式使用 currval 是否安全在交易之内或之外。来自 Postgresql 8.4 文档:
You can do this in two inserts, using
currval()
to retrieve the foreign key (provided that key is serial):The result:
Using currval in this way is safe whether in or outside of a transaction. From the Postgresql 8.4 documentation:
您可能需要使用 AFTER INSERT 触发器来实现这一点。 需要类似于:
after insert
的内容,因为您需要有 id 来引用它。希望这有帮助。编辑
触发器将在与触发它的命令相同的“块”中被调用,即使不使用事务 - 换句话说,它在某种程度上成为该命令的一部分 .. 因此,不存在在插入之间更改引用 id 的风险。
You may want to use
AFTER INSERT
trigger for that. Something along the lines of:after insert
is needed because you need to have the id to reference it. Hope this helps.Edit
A trigger will be called in the same "block" as the command that triggered it, even if not using transactions - in other words, it becomes somewhat part of that command.. Therefore, there is no risk of something changing the referenced id between inserts.