今日、コンパイルすべきではない面白いコードが出てきました。 FOR r IN ... LOOP
内のSELECT ... INTO
句を使用します。 Oracle 11iでコンパイルされるスクリプトは次のとおりです。このスクリプトは、パッケージでコンパイルされた実際のPL/SQLコードの短縮バージョンであり、本番環境で動作します。FOR r in(SELECT ... INTO ...)
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;
出力、実行すると、次のとおりです。私は無事select
文のINTO
一部を削除することができ、2)この構築物は無効であるべきいずれかのことを
rec: i= , t=
rec: i= , t=
私は 1を信じる)または少なくとも未定義の挙動を示す。
私の2つの仮定は正しいですか?
OracleドキュメントでSQL SELECT文が明示的に記述されていて、カーソルFORループに対してSELECT INTOが明示的に記述されていない場合は、特に注意してください。http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/cursor_for_loop_statement.htm#LNPLS1155 – Sathya
私はこれまで気付いたことがありますが、サポートドキュメントのどこにでもそれへの参照が見つかりませんでした。私は 'into '部分が静かに無視されていることを確かめています - あなたは明示的に' rec'フィールドに値を設定することができ、ループの中でも後でも変更されません。残念ながら引用が必要です... –
'INTO'節が削除されれば、すべてが完璧に動作します。値は' forループ 'からの' r.iとr.t'の出力で見ることができます。これはパーサが黙って無視することを証明します。 'DECLARE rec tq84_foo%rowTYPE; は におけるRの をBEGIN(、 トンrec.i INTO、rec.tを私を選択 - ???うーんtq84_foo FROM )を LOOP DBMS_OUTPUT.PUT_LINE ( 'REC:私は=' ||里|| '、t =' || rt ) ; END LOOP; END; / '本当に奇妙です! –