甲骨文。无法理解 FOR 如何与子查询 SELECT INTO 一起使用
Posted
技术标签:
【中文标题】甲骨文。无法理解 FOR 如何与子查询 SELECT INTO 一起使用【英文标题】:Oracle. Can't understand how FOR works with subquery SELECT INTO 【发布时间】:2015-10-15 08:21:12 【问题描述】:发现奇怪的东西。无法理解为什么 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
返回非空值
我当然明白:
FOR
在这种情况下不需要。 Count
没有 INTO
只返回一行。
我可以在没有INTO
的情况下使用它,它会起作用。
只是好奇它在上面的查询中是如何以及为什么起作用的。
为什么Oracle允许使用SELECT INTO
进行子查询很奇怪,因为通常情况下Oracle会返回编译错误ORA-06550
declare cnt number;
begin
select count(1) from (Select count(1) into cnt from v$session)
end;
or
如果第一个查询有效 - 为什么它不能正确返回 cnt 值?
【问题讨论】:
请看我的回答。您应该在 for select 语句中命名您的列。像处理表格行一样处理r
。
【参考方案1】:
正确的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;
【讨论】:
@RaduGheorghiu 我已经测试过了,没有问题。 我的错,我的代码出错了。你是对的。 是的,它有效。 +1回答。但这并不能解释为什么它与 INTO 一起工作不正确 @ViktorBardakov 没错,这还不清楚。我已对您的问题投了赞成票以引起更多关注 @sstan 你说得对,我已将第二个答案与第一个答案合并。【参考方案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
【讨论】:
以上是关于甲骨文。无法理解 FOR 如何与子查询 SELECT INTO 一起使用的主要内容,如果未能解决你的问题,请参考以下文章