甲骨文。无法理解FOR如何使用子查询SELECT INTO

时间:2015-10-15 08:21:12

标签: sql oracle plsql

发现奇怪的事情。无法理解为什么Oracle允许此查询以及为什么cnt变量在执行后不会更改:

declare cnt number;
begin
 for r in (Select count(1) into cnt from  v$session) loop
   dbms_output.put_line(cnt);
 END LOOP; 
end;

Select count(1) from v$session不返回空值

我当然明白了:

  1. 在这种情况下FOR不需要。没有Count的{​​{1}}只返回一行。
  2. 我可以在没有INTO的情况下使用它,它会起作用。
  3. 只是好奇它在上面的查询中的工作原理和原因。

    为什么Oracle允许使用INTO的子查询,这很奇怪,因为在常见情况下Oracle会返回编译错误ORA-06550

    SELECT INTO

    如果第一个查询有效 - 为什么它不能正确返回cnt值?

2 个答案:

答案 0 :(得分:4)

更正sql语句

试试这个

declare cnt number;
begin
 for r in (Select count(1) as cnt from  v$session) loop
   dbms_output.put_line(r.cnt);
 END LOOP; 
end;

<强>解释

select_statement中

SQL SELECT语句(不是PL / SQL SELECT INTO语句)。对于select_statement,PL / SQL声明,打开,从中提取和关闭隐式游标。但是,因为select_statement不是一个独立的语句,所以隐式游标是内部的 - 你不能用名称SQL引用它。

请参阅http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/cursor_for_loop_statement.htm#LNPLS1155

cnt变量被忽略,这可以通过以下示例证明,因为不会引发错误:

declare
  cnt       number;
  a_varchar varchar2(1);
begin
  for r in (Select 'AA' into a_varchar from v$session) loop
    dbms_output.put_line(a_varchar);
  end loop;
end;

答案 1 :(得分:2)

非常有趣,我会说这是一个错误,除了它是一个良性的。 INTO cnt位是有效的PL / SQL,但在此上下文中被忽略,可以通过简单的测试用例证明:

declare cnt number;
begin
 for r in (select count(1) into cnt from dual) loop
   dbms_output.put_line('cnt=' || cnt);
   dbms_output.put_line('r=' || r."COUNT(1)");
 end loop;
end;

如您所见,INTO子句被忽略,正如预期的那样,r记录被正确填充。我的11gR2实例上的输出:

cnt=
r=1