FOR r in(SELECT ... INTO ...)

Ren*_*ger 7 oracle plsql

今天,我遇到了一段有趣的代码,我认为不应该编译.它使用a中的一个SELECT ... INTO子句FOR r IN ... LOOP.这是一个在Oracle 11i上编译的脚本.该脚本是在包中编译的实际PL/SQL代码的缩短版本,在生产中运行.

create table tq84_foo (
   i number,
   t varchar2(10)
);

insert into tq84_foo values (1, 'abc');
insert into tq84_foo values (2, 'def');

declare

  rec tq84_foo%rowtype;

begin

  for r in (
     select     i,     t 
       into rec.i, rec.t -- Hmm???
       from tq84_foo
  )
  loop

    dbms_output.put_line('rec: i= ' || rec.i || ', t=' || rec.t);

  end loop;

end;
/


drop table tq84_foo purge;
Run Code Online (Sandbox Code Playgroud)

运行时的输出是:

rec: i= , t=
rec: i= , t=
Run Code Online (Sandbox Code Playgroud)

相信 1)我可以安全地删除声明的INTO一部分,select2)这个结构应该是无效的或至少表现出未定义的行为.

我的两个假设是对的吗?

Nim*_*rod 1

您的假设部分正确:

1) 是的,您可以安全地删除INTO该语句的一部分SELECT。但是您应该将循环中的行更改为以下格式:

dbms_output.put_line('rec: i= ' || r.i || ', t=' || r.t);
Run Code Online (Sandbox Code Playgroud)

这样它将从r变量中获取数据

SELECT ... INTO2) 这段代码的问题是,如果查询返回多于一行,则语法应该失败。如果它没有失败,那么它可能是一个错误并且会出现意外的行为。