INSERT RETURNING是否保证以“正确”的顺序返回内容?

时间:2011-03-25 23:52:33

标签: postgresql insert sql-returning

示例:

create table foo(
    id serial, 
    txt text
);

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

返回:

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

似乎返回值中的第一个 id始终是id的{​​{1}},第二个是'a'等等,但这是'b'的定义行为,还是在奇怪情况下可能失败的巧合?

3 个答案:

答案 0 :(得分:16)

我在the documentation中没有看到任何保证RETURNING订单的内容,所以我认为你不能依赖它。可能性是RETURNING订单与VALUES订单匹配,但我看不出任何关于VALUES将被插入的顺序的保证; VALUES几乎肯定会从左到右依次插入,但同样没有文件保证。

此外,关系模型是基于设置的,因此排序是由用户应用的东西而不是关系的固有属性。通常,如果无法明确指定排序,则没有隐含的排序。

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

答案 1 :(得分:9)

虽然文档并不完全清楚,但它确实说明了:

  

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

现在“类似于”不是一个铁定的保证,我raised this for discussion on the mailing list ......但实际上,PostgreSQL不会混淆RETURNING中值的顺序。即使我们想进行优化,我们也不可能做到这一点,因为太多的应用程序依赖于它的输入顺序相同。

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

答案 2 :(得分:4)

虽然这对现在没有帮助,但9.1会包含"writeable common table expressions"。这是WITH syntax的正式名称。 (Wikipedia。)

这项新功能应该允许您将INSERT ... RETURNING置于WITH内,提供别名,然后SELECT使用普通旧版ORDER BY进行特定排序子句。