如何使用批量收集来替换此游标以进行循环

时间:2014-10-02 14:42:24

标签: sql oracle plsql

DECLARE 
L_DEPT_ID employees_test_1.department_id%type;
L_DEPT_NAME VARCHAR(255) := '&2';
columns_updated VARCHAR(255) := 'My check is hopes';

CURSOR CHECK_1 
IS
SELECT first_name, last_name, job_id, salary, manager_id, department_id, COMMENTS_RESTORE
from employees_test_1
where salary > 1000
and department_id=L_DEPT_ID;

BEGIN

SELECT department_id
INTO L_DEPT_ID
FROM DEPARTMENTS
WHERE DEPARTMENT_NAME=L_DEPT_NAME;



FOR C1 IN CHECK_1
LOOP
UPDATE employees_test_1 BRD
SET BRD.COMMENTS_RESTORE=columns_updated
WHERE BRD.first_name=C1.first_name
AND BRD.salary=C1.salary
AND BRD.last_name=C1.last_name;
COMMIT;
END LOOP;
END;

您好,我只更新了此查询中的一列。但这需要花费很多时间。你能告诉我在哪里可以调整这个查询。

1 个答案:

答案 0 :(得分:3)

你不需要在这里进行批量收集,只需要一个带有JOIN的子查询。

UPDATE employees_test_1 BRD
SET BRD.COMMENTS_RESTORE=columns_updated 
WHERE EXISTS (
    SELECT 1
    FROM employees_test_1 ET1
    INNER JOIN DEPARTMENTS D ON ET1.department_id = ET1.department_id
    WHERE D.DEPARTMENT_NAME = L_DEPT_NAME
    AND ET1.first_name = BRD.first_name
    AND ET1.salary = BRD.salary
    AND ET1.last_name = BRD.last_name
)

你仍然在做一堆字符串比较,并且有一个自引用子查询,所以这将是一个耗时的操作...但这应该比光标快一点。

编辑:通过BULK操作添加替代方式。假设您在employees_test_1表中有一个主键列

DECLARE
TYPE employee_block IS RECORD (first_name VARCHAR2(50), salary NUMBER, last_name VARCHAR2(50);
TYPE employee_ids_t IS TABLE OF employee_block
l_employees   employee_ids_t;

SELECT et.first_name, et.salary, et.last_name
BULK COLLECT INTO l_employees
FROM employees_test_1 et
INNER JOIN DEPARTMENTS D ON D.department_id = et.department_id
WHERE D.DEPARTMENT_NAME = L_DEPT_NAME
AND salary > 1000;

FORALL indx IN 1..l_employees.COUNT
UPDATE employees_test_1 BRD
SET BRD.COMMENTS_RESTORE = columns_updated
WHERE BRD.first_name = l_employees(indx).first_name
AND BRD.salary = l_employees(indx).salary
AND BRD.last_name = l_employees(indx).last_name;

Haven没有对此进行过测试,所以语法可能会触及......这里有一个很好的参考来帮助你。 http://www.oracle.com/technetwork/issue-archive/2012/12-sep/o52plsql-1709862.html