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

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

今天,我遇到了一段我认为不应该编译的有趣代码。它在 FOR r IN ... LOOP 中使用 SELECT ... INTO 子句。这是一个在 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;

当运行时的输出是:

rec: i= , t=
rec: i= , t=

相信 1) 我可以安全地删除 select 语句的 INTO 部分和 2) 这个构造应该是无效的或展示至少是未定义的行为。

我的两个假设是否正确?

您的假设部分正确:

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

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

这样它将从 r 变量

中获取数据

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