2009-11-13 68 views
7

這是「有更好的方式」的問題之一。讓我來解決這個問題,然後我會給你我的黑客解決方案,也許你可以提出一個更好的解決方案。謝謝!重置PL/SQL中的關聯數組?

讓我們PL的這個小珍聞/ SQL

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; 

這是否有意義?我基本上需要重置它。如果它是一個從零開始的數字,我可以說數字:= 0;在每一次迭代的頂部,並完成它。但這不是一個數字,它是一種我可以用一個乾淨的= 0重置的類型。

反正到我的黑客:

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; 

我想,如果我能設法保持同一類型的成員在原來的狀態,那麼我可以只設置工作變回任何值是原創的。而且,令人驚訝的是,它的工作原理(我認爲)。但是有一個更好的方法。誰能幫忙?

T'anks!

+1

小挑剔:你不需要申報'row_monkey猴子%ROWTYPE;'。像這樣的一個遊標FOR循環爲你做聲明,並且僅限於循環體。在這段代碼中,變量被聲明瞭兩次,而內部版本則隱藏了外部變量。這不是問題 - 只是認爲我會爲其他人閱讀。 – AdamRossWalker 2015-11-23 14:02:24

回答

18

最簡單的方法:

arr_foos.Delete(); 

另一種方法是申報FOR循環內的變量。這樣它將被重新創建每個通行證。

像這樣:

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

謝謝!我沒有意識到你可以在BEGIN之後說DECLARE。 (: – steve 2009-11-13 21:22:20

+2

)你可以嵌套任意次數,這樣你也可以在更小的代碼塊中捕獲異常(例如C#或Java中的try/catch),在我看來非常有用的功能 – Majkel 2009-11-13 21:24:47

1

你要去動物園從表中的數據讀入一個集合?然後有一個更好的辦法:

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; 

散裝收集自動讀取前清除集合,它的工作速度更快然後在循環讀取一行接一行。不幸的是,它並不適用於記錄,因此每個字段需要幾個PL/SQL表。

你可以在這裏找到更多的信息:Retrieving Query Results into Collections with the BULK COLLECT Clause

+0

好的提示,謝謝 – steve 2009-11-16 12:15:44