在 PL/SQL 中重置关联数组?

Posted

技术标签:

【中文标题】在 PL/SQL 中重置关联数组?【英文标题】:Resetting an Associative array in PL/SQL? 【发布时间】:2009-11-13 20:47:51 【问题描述】:

这是“必须有更好的方法”的问题之一。让我设置问题,然后我会给你我破解的解决方案,也许你可以提出一个更好的解决方案。谢谢!

让我们来看看这个关于 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;

这有意义吗?我基本上需要将其重置为某些东西。如果它是一个从零开始的数字,我可以说 number:=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;

我想如果我能够设法将同一类型的成员保留在原始状态,那么我可以将工作变量设置回原始值。而且,令人惊讶的是,它有效(我认为。)但必须有更好的方法。有人可以帮忙吗?

坦克!

【问题讨论】:

轻微挑剔:你不需要声明row_monkey monkeys%rowtype;。像这样的游标 FOR 循环会为您进行声明,并且仅限于循环体。在这段代码中,变量被声明了两次,并且内部版本隐藏了外部版本。不过这不是问题——只是想我会为其他阅读者添加这个。 【参考方案1】:

最简单的方法:

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;

【讨论】:

谢谢!我没有意识到你可以在 BEGIN 之后说 DECLARE。 (: 您可以嵌套任意次数。这样,您还可以在较小的代码块中捕获异常(例如 C# 或 Java 中的 try/catch)。在我看来非常有用的功能。 原因不是“你可以在 BEGIN 之后说 DECLARE”。您可以有许多相互嵌套的 PL/SQL 块。【参考方案2】:

您是否要将 zoo 表中的数据读入集合中?那么还有更好的办法:

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;

Bulk collect 在获取之前会自动清除集合,并且它的工作速度比循环中逐行读取更快。不幸的是,它不适用于记录,因此每个字段都需要多个 PL/SQL 表。

您可以在此处找到更多信息:Retrieving Query Results into Collections with the BULK COLLECT Clause

【讨论】:

派对迟到:幕后的'for row in cursor'语法也会导致批量收集,它会一次获取100条记录。只有在使用显式提取时才会真正发生缓慢的“逐行”提取。

以上是关于在 PL/SQL 中重置关联数组?的主要内容,如果未能解决你的问题,请参考以下文章

从 PL/SQL 关联数组中的元素获取不同的值

如何获取 PL/SQL 关联数组 DS 的 NULL 条件检查

更新另一列时,使用列名作为 PL/SQL 关联数组的键

PL/SQL集合(table)嵌套表操作实例讲解实例

SQL记录-PLSQL集合

PL/SQL数组