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

Fun*_*lad 18 postgresql insert sql-returning

例:

create table foo(
    id serial, 
    txt text
);

insert into foo(txt) values ('a'),('b'),('c') returning id;
Run Code Online (Sandbox Code Playgroud)

返回:

 id 
----
  1
  2
  3
(3 rows)
Run Code Online (Sandbox Code Playgroud)

似乎是在第一次 id的返回值永远是id'a',第二对'b'等,但该定义的行为insert into,抑或是可以在奇数的情况下失败是巧合吗?

mu *_*ort 17

我没有在文档中看到任何保证订单的内容,RETURNING因此我认为您不能依赖它.可能的情况是RETURNING订单将与订单匹配,VALUES但我看不到任何关于VALUES将插入订单的保证; 将VALUES几乎肯定会以被插入从左至右但同样,没有记录在案的保证.

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

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

  • 同意,*绝对*不要依赖它。PostgreSQL 完全有权对输入进行排序,但是会导致最佳的插入性能,并且如果曾经实现索引组织的表,它可能会实现。 (2认同)
  • @Craig:我认为*指定/保证行为*和*附带/经验验证行为*之间的区别是人们必须学习的艰难教训之一; 我很幸运,很早就通过与十个不同的C编译器和Unixen一起工作来学习.这就是为什么我总是倾向于"尝试它,看看它做什么"的软件方法,"尝试它,看看它做了什么,然后从规范中证明这种行为"更好,但我更喜欢从规格开始假设不存在任何东西. (2认同)

Cra*_*ger 12

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

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

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

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


Cha*_*les 7

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

这个新功能应该让您将您的内容放入INSERT ... RETURNINGa 中WITH,给出一个别名,然后SELECT使用普通的旧子句按照特定的顺序进行对抗ORDER BY

  • 这很有趣,但只是无关紧要的。*仅当*输入顺序也可以用明确且等效的“ORDER BY”来表达时,它才可以用作OP所要求的近似值。 (6认同)