示例:
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'
的定义行为,还是在奇怪情况下可能失败的巧合?
答案 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
进行特定排序子句。