6

在下面的例子中,我总是会得到“1, 2”,还是有可能得到“2, 1”,你能告诉我你在文档中的哪个地方看到了保证是否存在?

如果答案是肯定的,这意味着没有ORDER BYORDER SIBLINGS没有办法确定 SELECT 语句中的结果集顺序。

CREATE TYPE temp_row IS OBJECT(x number);
/

CREATE TYPE temp_table IS TABLE OF temp_row;
/

CREATE FUNCTION temp_func
RETURN temp_table PIPELINED
IS
BEGIN
    PIPE ROW(temp_row(1));
    PIPE ROW(temp_row(2));
END;
/

SELECT * FROM table(temp_func());

谢谢你。

4

3 回答 3

5

我认为文档中没有任何地方可以保证返回数据的顺序。

有一个 2003 年的旧Tom Kyte 线程(因此可能已经过时),它指出不建议依赖隐式顺序,原因与您不依赖普通 SQL 中的顺序相同。

第一个:SQL 语句中从表函数返回的行的顺序是否与将条目“通过管道”“传送”到内部集合中的顺序完全相同(因此不需要 order by 子句)?

...

跟进 2003 年 5 月 18 日 - 世界标准时间上午 10 点:

1)也许,也许不是,我不会指望它。如果没有 order by,您不应该指望结果集中的行顺序。如果你加入或做一些更复杂的事情,然后简单地“从表中选择*(f(x))”,这些行很可能会以其他顺序返回。

从经验上看——它们似乎在被传送时又回来了。我不相信有文件证明是这样的。

事实上,类型为 NESTED TABLE 的集合被记录为明确 没有保留 order 的能力

为了安全起见,如果您希望查询结果排序,您应该像往常一样在查询中声明明确的 ORDER BY。

话虽如此,我已经使用了您的函数并运行了 1000 万次迭代,以检查隐式顺序是否被破坏;不是。

SQL> begin
  2    for i in 1 .. 10000000 loop
  3      for j in ( SELECT a.*, rownum as rnum FROM table(temp_func()) a ) loop
  4
  5         if j.x <> j.rnum then
  6            raise_application_error(-20000,'It broke');
  7         end if;
  8      end loop;
  9    end loop;
 10  end;
 11  /

PL/SQL procedure successfully completed.
于 2013-05-23T12:15:33.350 回答
1

此过程逻辑的工作方式与基于表的查询不同。您不能依赖从表中选择的顺序的原因是,您不能依赖 RDBMS 将行标识为所需集合的一部分的顺序。这部分是因为执行计划发生了变化,部分是因为很少有情况可以预测表中行的物理顺序。

但是,在这里您要从一个函数中进行选择,该函数可以保证从函数发出行的顺序。在没有连接、聚合或其他任何东西的情况下(即直接“从表(函数)中选择...”),我可以肯定行顺序是确定性的。

除非有明确的 order-by,否则该建议不适用于涉及表的地方,因此,如果您从不使用 order-by 的查询中加载 pl/sql 集合,那么当然是集合中行的顺序不是确定性的。

于 2013-05-23T12:40:01.430 回答
0

已接受答案中的 AskTom 链接此时已损坏,但我发现了更新但非常相似的问题。在一些“对乒乓球的误解”之后,Connor McDonald 最终承认,在涉及并行性和引用光标的某些条件下,排序是稳定的,并且仅与当前版本相关。引文:

并行性是这里的(潜在)风险。就目前而言,流水线函数只有在将引用光标作为输入时才能并行运行。当然,不能保证将来不会改变。因此,您可以假设当前版本中您将按顺序恢复行,但您永远不能 100% 相信现在和永远都是这种情况。

因此,不保证未来的版本。

有问题的函数将通过此标准,因此它应该提供稳定的排序。但是,我个人不会相信它。我的情况(当我发现这个问题时)更简单:从字面上指定的集合中进行选择——select column_value from table(my_collection(5,3,7,2))无论如何我更喜欢数据和索引之间的显式配对。这不是那么难,也不会更长。

Oracle 应该向 Postgres 学习如何解决这种情况,unnest(array) with ordinality后者是清晰易懂、值得信赖和有据可查的特性。

于 2020-11-11T21:30:02.040 回答