其中哪一个更具性能。
版本1 使用Cursor For Loop
DECLARE
total_val number(6);
CURSOR c1 IS
SELECT * FROM emp
;
BEGIN
total_val := 0;
FOR emp_rec IN c1
LOOP
total_val := total_val + emp_rec.sal;
END LOOP;
DBMS_OUTPUT.PUT_LINE('TOTAL SALARIES: ' || total_val);
END;
版本2 首先使用Bulk Collect
将所有行放入PLSQL集合,然后迭代它。
DECLARE
total_val number(6);
CURSOR c1 IS
SELECT * FROM emp
;
TYPE emp_recs_type IS TABLE OF emp%ROWTYPE;
emp_recs emp_recs_type;
BEGIN
total_val := 0;
OPEN c1;
FETCH c1 BULK COLLECT INTO emp_recs;
CLOSE c1;
FOR l_index IN emp_recs.FIRST..emp_recs.LAST
LOOP
total_val := total_val + emp_recs(l_index).sal;
END LOOP;
DBMS_OUTPUT.PUT_LINE('TOTAL SALARIES: ' || total_val);
END;
请假设Cursor
可能返回多行,可能是数十万或更多。
答案 0 :(得分:2)
找出答案的最佳方法是设置实验并进行尝试。
当然,对于您的示例,最好的代码是:
DECLARE
total_val number(6);
BEGIN
SELECT SUM(sal) INTO total_val FROM emp;
DBMS_OUTPUT.PUT_LINE('TOTAL SALARIES: ' || total_val);
END;
然而,我意识到这只是一个简单的例子!
理论上使用BULK COLLECT应该会更好,但实际上这些天(肯定是在11G中)Oracle无论如何都会以100行的批量隐藏批量提取 - 请参阅this AskTom thread。
如果您自己使用BULK COLLECT并且可能存在未指定数量的行,则应使用LIMIT子句,否则可能会遇到内存问题。对于你的例子,这将是:
DECLARE
total_val number(6);
CURSOR c1 IS
SELECT * FROM emp
;
TYPE emp_recs_type IS TABLE OF emp%ROWTYPE;
emp_recs emp_recs_type;
BEGIN
total_val := 0;
OPEN c1;
LOOP
FETCH c1 BULK COLLECT INTO emp_recs LIMIT 100;
EXIT WHEN c1.COUNT = 0;
FOR l_index IN emp_recs.FIRST..emp_recs.LAST
LOOP
total_val := total_val + emp_recs(l_index).sal;
END LOOP;
END LOOP;
DBMS_OUTPUT.PUT_LINE('TOTAL SALARIES: ' || total_val);
CLOSE c1;
END;