22

例子:

create table foo(
    id serial, 
    txt text
);

insert into foo(txt) values ('a'),('b'),('c') returning id;

回报:

 id 
----
  1
  2
  3
(3 rows)

似乎返回值中的第一个总是for ,第二个 for等等,但这是定义的行为,还是在奇怪的情况下可能会失败的巧合? idid'a''b'insert into

4

3 回答 3

20

虽然文档并不完全清楚,但它确实指出:

如果 INSERT 命令包含 RETURNING 子句,则结果将类似于 SELECT 语句的结果,该语句包含在 RETURNING 列表中定义的列和值,根据命令插入的行计算。

现在“类似于”并不是一个铁定的保证,我已经在邮件列表中提出了这个讨论......但实际上,PostgreSQL 不会弄乱RETURNING. 即使我们想要进行优化,我们也不太可能做到这一点,因为太多的应用程序依赖于它与输入的顺序相同。

所以......对于INSERT INTO ... VALUES (...), (...), ... RETURNING ...并且对于INSERT INTO ... SELECT ... ORDER BY ... RETURNING ...假设结果关系与输入的顺序相同应该是安全的。

于 2015-01-17T04:37:33.497 回答
19

我在文档中看不到任何保证订单的内容,RETURNING因此我认为您不能依赖它。奇怪的是RETURNING订单将与订单匹配,VALUES但我看不到任何关于VALUES将插入什么订单的保证;VALUES几乎可以肯定会按从左到右的顺序插入,但同样没有书面保证。

此外,关系模型是基于设置的,因此排序是用户应用的东西,而不是关系的固有属性。一般来说,如果无法明确指定排序,则不存在隐含排序。

执行摘要:您看到的顺序可能总是会发生,但不能保证,所以不要依赖它。

于 2011-03-26T00:21:41.357 回答
4

虽然现在这对您没有帮助,但 9.1 将包括“可写公用表表达式”。这是WITHsyntax的正式名称。(维基百科。)

这个新能力应该让你把你的INSERT ... RETURNING放在 a 里面WITH,给一个别名,然后用一个普通的旧子句SELECT用一个特定的顺序来反对它。ORDER BY

于 2011-03-26T05:17:01.363 回答