-2

我正在研究一段我想要优化的 sql。我有一堆游标。我想知道是否可以使用其他东西代替游标。我正在考虑使用某种变量,填充它们,并在其余的处理中避免数据库连接(我有一个复杂的处理)。

例如,我有一段代码,例如:

TYPE rec_basket IS RECORD (
 FIELD1 VARCHAR2(40),
 FIELD2 NUMBER(10),
 FIELD3 VARCHAR2(6)
 );

 TYPE tab_basket IS TABLE OF rec_basket
 INDEX BY BINARY_INTEGER;

………………………………………………………………………………

CURSOR cur_baskets
   IS
select * from toto

......................

 FOR i IN cur_baskets
   LOOP
  l_tab_basket (l_nbasket).field1 := i.field1;
  l_tab_basket (l_nbasket).field2 := i.field2;
  l_tab_basket (l_nbasket).field3  := i.field3;
  l_nbasket := l_nbasket + 1;    
   END LOOP;

使用游标并填充 l_tab_basket 变量是最好的方法吗?我在代码中的某处使用了 l_tab_basket (index)。我放置这段代码的原因是我想将这种机制用于我的其他游标。实际上我在另一个光标内有一个光标。对于他们每个人的每一行,我都有一些治疗。我想用其他东西替换光标,但我不知道怎么做。谢谢。

4

2 回答 2

2

您可以使用 BULK COLLECT 将所有记录提取到嵌套表中。这适用于 10g+:

SQL> DECLARE
  2     TYPE rec_basket IS RECORD(
  3        field1 VARCHAR2(40),
  4        field2 NUMBER(10),
  5        field3 VARCHAR2(6));
  6     TYPE tab_basket IS TABLE OF rec_basket INDEX BY BINARY_INTEGER;
  7     l_tab_basket tab_basket;
  8  BEGIN
  9     SELECT 'a', ROWNUM, 'b'
 10       BULK COLLECT INTO l_tab_basket
 11       FROM dual CONNECT BY LEVEL <= 1000;
 12  END;
 13  /

PL/SQL procedure successfully completed

请记住,Oracle 10g 会自动从 pl/sql 中批量 (100) 的隐式游标中获取记录,因此收益充其量应该是微不足道的:您可能会花费更多时间查询数据库而不是构建数组,除非数组真的是大(在这种情况下使用嵌套表是否明智?)

于 2010-09-02T16:09:33.280 回答
1

您的代码逻辑不是很清楚。你还没有写完整的程序。让我们检查一下:

CURSOR cur_baskets IS select * from toto

这里从表 toto 中读取值并将其放入游标中。

在以下几行中,从光标中读取值并将其放入 l_tab_basket。

FOR i IN cur_baskets 循环 l_tab_basket (l_nbasket).field1 := i.field1; l_tab_basket (l_nbasket).field2 := i.field2; l_tab_basket (l_nbasket).field3 := i.field3; l_nbasket := l_nbasket + 1;
结束循环;

因此,相同的值将两次进入局部变量。这是可以避免的。您可以找到直接插入或更新目标表的方法。

您可以尝试批量收集。如果 toto 很小,您可以在不使用游标的情况下插入或更新目标表。

于 2010-09-04T14:46:45.017 回答