我正在研究一些我想要优化的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 (索引)。 我放这段代码的原因是我想将这个机制用于我的其他游标。 实际上我有一个光标在另一个。而且对于他们每个人的每一行我都有一些治疗方法。我想用其他东西替换游标,但我不知道如何。 感谢。
答案 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很小,则可以在不使用游标的情况下插入或更新目标表。