2009-11-13 12 views
7

Bu "daha iyi bir yol olmalı" sorularından biri. Sorunu kurmama izin verin, sonra size saldırıya uğramış çözümümüzü vereceğim ve belki de daha iyi bir çözüm önerebilirsiniz. Teşekkürler!PL/SQL'de İlişkilendirilmiş bir diziyi sıfırlama?

mantıklı

DECLARE 
TYPE foo_record IS RECORD (foo%type, bar%type); 
TYPE foo_records IS TABLE OF foo_record INDEX BY PLS_INTEGER; 
arr_foos foo_records; 

CURSOR monkeys is SELECT primates FROM zoo; 
row_monkey monkeys%rowtype; 
BEGIN 
FOR row_monkey IN monkeys loop 
    /* 
    at this point in each iteration I need to have the associative array 
    arr_foos in its original state. if this were java, I'd declare it 
    right here and its scope would be limited to this iteration. However, 
    this is not java, so the scope of the array is effectively global and 
    I can't have one iteration's data meddle with the next. 
    */ 
    null; 
END LOOP; 
END; 

mu SQL/PL bu küçük çerez almak Lets? Temel olarak bir şeye sıfırlamam gerekiyor. Sıfırdan başlayan bir sayı olsaydı, sadece sayı söyleyebilirdim: = 0; Her iterasyonun en üstünde ve onunla yapılabilir. Ama bu bir sayı değil, sadece temizle sıfırlayabileceğim bir tür: = 0.

Neyse, benim hack üzerine:

DECLARE 
TYPE foo_record IS RECORD (foo%type, bar%type); 
TYPE foo_records IS TABLE OF foo_record INDEX BY PLS_INTEGER; 
arr_foos foo_records; 
arr_foos_reset foo_records; 

CURSOR monkeys is SELECT primates FROM zoo; 
row_monkey monkeys%rowtype; 
BEGIN 
FOR row_monkey IN monkeys loop 
    arr_foos := arr_foos_reset; 
    null; 
END LOOP; 
END; 

ben orijinal bir durumda aynı türden bir üyesini korumak için yönetebilirsiniz eğer, o zaman sadece geri ne olursa olsun değerine çalışma değişkeni ayarlayabilirsiniz düşündüm orijinaldir. Ve şaşırtıcı bir şekilde, yeterince işe yarıyor (bence). Ama daha iyi bir yol olmalı. Biri yardım edebilir mi?

T'anks!

+1

Minör nitpick: Eğer 'row_monkey maymunlar% Rowtype ilan etmek gerekmez;'. Bu gibi bir İmleci Döngü döngüsü sizin için bir beyanname yapar ve döngü gövdesi ile sınırlıdır. Bu kodda, değişken iki kez bildirilir ve iç sürüm dışını gölgeler. Bu bir problem değil - sadece bunu okuyan herkes için ekleyeceğimi düşündüm. – AdamRossWalker

cevap

18

kolay yolu:

arr_foos.Delete(); 

Diğer bir yol FOR döngü içindeki değişkeni bildirmektir. Bu şekilde her geçiş için yeniden oluşturulacak.

DECLARE 
TYPE foo_record IS RECORD (foo%type, bar%type); 
TYPE foo_records IS TABLE OF foo_record INDEX BY PLS_INTEGER;  

CURSOR monkeys is SELECT primates FROM zoo; 
row_monkey monkeys%rowtype; 
BEGIN 
FOR row_monkey IN monkeys loop 
    DECLARE 
    arr_foos foo_records; 
    BEGIN 
    null; 
    END; 
END LOOP; 
END; 
+2

Teşekkürler! BEGIN'den sonra DECLARE diyebileceğinizi anlayamadım. (: – steve

+2

Herhangi bir sayıyı yuvalayabilirsiniz. Bu şekilde, daha küçük kod bloklarında istisnaları da yakalayabilirsiniz (C# veya Java'da try/catch gibi) .Bu fikrimde çok kullanışlı özellik – Majkel

1

bir koleksiyon haline hayvanat bahçesi tablodan veri okumak mısın: Bunun gibi

? otomatik

DECLARE 
    type foos_ts is table of zoo.foo%type index by pls_integer; 
    foos foos_t; 
BEGIN 
    select foo 
    bulk collect into foos 
    from zoo; 
    ... 
END; 

Toplu toplamak getirmeden önce toplanmasını temizler ve daha hızlı döngü içinde satır-by-satır okuma sonra çalışır: O zaman daha iyi bir yoldur. Ne yazık ki, kayıtlarla çalışıyor, bu yüzden her alan için birkaç PL/SQL tablosuna ihtiyacınız olacak.

Burada ek bilgi bulabilirsiniz: Retrieving Query Results into Collections with the BULK COLLECT Clause

+0

iyi ipucu, teşekkürler – steve