2009-11-13 67 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