Oracle优化查询避免游标

时间:2010-09-02 15:55:43

标签: oracle cursors

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

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

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 (索引)。 我放这段代码的原因是我想将这个机制用于我的其他游标。 实际上我有一个光标在另一个。而且对于他们每个人的每一行我都有一些治疗方法。我想用其他东西替换游标,但我不知道如何。 感谢。

2 个答案:

答案 0 :(得分: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)中的隐式游标中获取记录,因此增益应该是最小的:除了数组之外,您可能会花费更多时间来查询数据库而不是构建数组真的很大(在这种情况下,使用嵌套表是明智的吗?)

答案 1 :(得分:1)

您的代码逻辑不是很清楚。你还没有写完整个程序。让我们来看看:

CURSOR cur_baskets    IS 从托托

中选择*

此处从表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;
   END LOOP;

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

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