2015-01-12 22 views
7

Bugün, derlemem gerektiğini düşündüğüm komik bir kod parçasıyla karşılaştım. Bir FOR r IN ... LOOP içinde bir SELECT ... INTO yan tümcesi kullanır. İşte Oracle 11i'yi derleyen bir betik. Komut, bir pakette derlenen gerçek PL/SQL kodunun kısaltılmış halidir.İÇİNDİR (SELECT ... INTO ...)

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

ben güvenle select beyanı INTO bölümünü kaldırabilir) 1 inanmak ve 2) bu yapı geçersiz veya gerektiği ya o: çalıştırdığınızda

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; 

çıkışı, olduğu en az tanımsız davranış sergiler.

İki varsayımım doğru mu?

+0

THat, Oracle belgelerinin açık bir şekilde SQL select deyiminden bahsedildiği zaman gariptir, espri için http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/cursor_for_loop_statement.htm#LNPLS1155 – Sathya

+1

Bunu daha önce farkettim, ancak destek dokümanlarında herhangi bir yerde herhangi bir referans bulamadım. Eminim '' ın 'bölümü sessizce göz ardı edilir - 'rec' alanlarını açıkça doldurabilir ve döngü içinde ya da sonra değiştirilmez - ve kaldırılması güvenlidir; ama ne yazık ki gerekli, ne yazık ki ... –

+0

Ve INTO' fıkra kaldırılırsa, her şey mükemmel çalışır, değerler "for döngüsünden" r.i ve r.t için çıktı olarak görülebilir. Hangi ayrıştırıcının sessizce görmezden geldiğini kanıtlıyor. DÜZENLEME tq84_foo% rowTYPE; ': = I rec' || ri ( ÇEVRİM tanımına uygun - (tq84_foo DAN ??? Hmm rec.i, rec.t İÇİNE, t i SEÇ) R için BEGIN || ', t =' || rt ) ; END LOOP; END; / 'Gerçekten garip! –

cevap

1

Kişisel varsayımlar kısmen haklısınız:

1) Evet, güvenle SELECT beyanı INTO bölümünü kaldırabilirsiniz. Ama bu formata döngüde satır değiştirmelisiniz:

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

Bu şekilde bu kodla r değişken

2) sorunun dışarı veri alacak olması SELECT ... INTO sözdizimi sorgu birden fazla satır döndürürse başarısız olur. Başarısız olmazsa, bir hata olabilir ve beklenmedik davranışlara sahip olacaktır.