【问题标题】:Why does a connect by expression in a FOR loop, execute only once?为什么 FOR 循环中的连接表达式只执行一次?
【发布时间】:2014-05-13 23:28:28
【问题描述】:

我刚刚发现我认为在 PLSQL 与 Oracle 中的 SQL 中有些出乎意料的行为。

如果我在 SQLDeveloper 上运行此查询,我会得到 5 个结果:

select level lvl from dual connect by level <=5;

但是如果我在 SQLDeveloper 中运行这条语句:

declare
  w_counter number :=0;
begin
  for REC in (select level lvl from dual connect by level <=5)
  loop
    w_counter := w_counter+1;
  end loop;
  dbms_output.put_line('W_COUNTER: '|| w_counter);
end;

变量 w_counter 以值 1 结束(奇怪)

但最奇怪的是,如果我将查询封装在子查询中......类似于:

declare
  w_counter number :=0;
begin
  for REC in (select * from (select level lvl from dual connect by level <=5))
  loop
    w_counter := w_counter+1;
  end loop;
  dbms_output.put_line('W_COUNTER: '|| w_counter);
end;

w_counter 变量以值 5 结束...

对此你有什么想说的?

我正在使用 Oracle 9.2i

【问题讨论】:

  • 对于 Oracle 11g 中的两个块,我得到了 5。不幸的是我没有 9i!
  • 听起来像是一个优化器的错误......你能尝试在没有任何优化的情况下运行 PL/SQL 吗?我猜优化器看到了双重选择,推断双重选择只会返回一行并将循环剥离到单个调用......只是一个疯狂的猜测;-)
  • 两个块我都得到 5。我在 Oracle 10G 上。如果我在 9.2.0.7.0 上尝试此操作,我会看到与您相同的结果。
  • 这是一个错误。对 9.2 的 Premier 支持已于 2007 年到期 它已在更高版本中修复。你真的应该考虑升级你的服务器 - 我们在 11gR2 上,我认为我们落后于时代......对不起,我认为你需要登录 Oracle 支持才能看到我在下面发布的链接
  • 在 asktom.oracle.com 上查看此主题。 asktom.oracle.com/pls/apex/…Tom Kyte 在其他线程上解释说,9i 和 10g 之间存在优化器差异。

标签: sql oracle plsql oracle9i


【解决方案1】:

It's a bug 在 Oracle 9i confirmed up to 9.2.0.8 的一个版本中,但不超过。

之前在Ask Tom 上讨论过,回复只是“sqlplus 做到了”

对 Oracle 9.2 ended on 2007-07-31 的高级支持和扩展支持已于 2010 年 6 月 30 日结束。要解决此问题,建议您升级到当前版本的 Oracle;如果不能,你应该修补你的数据库超过 9.2.0.8 版本。

【讨论】:

  • 可以添加bug编号吗?根据前面的 cmets,这是一个错误是相当明显的。
  • @GuidoLeenders 我查看了但找不到错误编号。我添加了这个答案来总结 cmets,以防没有提供更好的答案。我将其标记为社区 wiki,因此我不会因为重复其他人所说的话而获得任何积分。
  • @jonearles:那就不要发布它作为答案。这应该是一条评论。
  • 如果您不喜欢这个答案,请编辑。这就是为什么它是一个社区维基。所有的 cmets 基本上都在说“这是一个错误”。这个问题值得回答,即使它不是一个很好的问题。没有人想通读所有这些 cmets。我从this thread得到这个想法。
猜你喜欢
  • 2017-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-22
  • 1970-01-01
  • 1970-01-01
  • 2017-10-13
相关资源
最近更新 更多