问题描述
-
IN_DATE
被声明为日期,因此您无需将其传递给TO_DATE()
。 - 您只需要一个游标循环;如果
employee_id
出于某种原因要一起处理所有更新,则可以添加一个order by
子句。 - 您根本不需要动态sql。您可以将游标中的值用作静态sql更新的一部分。
因此,具有单个循环的简单版本可能类似于:
CREATE OR REPLACE PROCEDURE sp_run_employee_updates (p_date IN DATE) IS
CURSOR c_updates IS
SELECT *
FROM bi_employee_update
WHERE effective_date = p_date
AND executed = 'N'
AND activity_id = '0'
FOR UPDATE;
BEGIN
-- loop around all pending records
FOR r_update IN c_updates LOOP
-- apply this update to the bi_employee record
UPDATE bi_employee
SET col1 = r_update.col1, col2 = r_update.col2
WHERE emp_id = r_update.employee_id;
-- mark this update as executed
UPDATE bi_employee_update
SET executed = 'Y'
WHERE CURRENT OF c_updates;
END LOOP;
END sp_run_employee_updates;
这是使用for update
andwhere current
of
构造来锁定您正在使用的行并简化更新;请参阅此处的文档。
值得一提的是,如果其中一个effective_date
或p_date
一个没有时间部分,它们将不匹配。这不太可能p_date
,但更难猜测effective_date
。如果确实如此,那么您要么需要trunc()
它,要么用它between
寻找一段时间。
解决方法
我需要在存储过程中动态创建和执行查询。
我有两个表user和user_updates。
员工表有 emp_id,username,division,product,region,title etc.
Employee_updates具有类似以下的列 emp_id,effective_date,column_name,new_value etc.
基本上,这就是我想要做的。
-
获取所有在给定生效日期user_udates表中有更新的员工。
-
遍历每位员工。
-
获取给定生效日期的每位员工的所有更新。员工可能在employee_updates表中具有一个或多个更新。
-
根据这些更新创建动态的“ UPDATE”查询,例如
update employee set col1 = new_val_1,col2 = new_val_2 where emp_id = ?
这是我到目前为止所做的
create or replace
PROCEDURE SP_RUN_EMPLOYEE_UPDATES
(
IN_DATE IN DATE
)
IS
update_sql varchar2(225);
employee_id BI_EMPLOYEE_UPDATE.employee_id%TYPE;
CURSOR employees
IS SELECT distinct(employee_id)
FROM BI_EMPLOYEE_UPDATE
WHERE EFFECTIVE_DATE = to_date(IN_DATE,'dd-mm-yy')
AND EXECUTED = 'N' AND ACTIVITY_ID = '0'
;
CURSOR e_updates
IS SELECT *
FROM BI_EMPLOYEE_UPDATE
WHERE EFFECTIVE_DATE = to_date(IN_DATE,'dd-mm-yy')
AND EXECUTED = 'N'
AND ACTIVITY_ID = '0'
and employee_id = employee_id ;
BEGIN
OPEN employees;
LOOP
FETCH employees into employee_id;
EXIT WHEN employees%NOTFOUND;
FOR e_update in e_updates
update_sql := 'UPDATE BI_EMPLOYEE SET ';
LOOP
-- create dynam,ic update statment
UPDATE BI_EMPLOYEE_UPDATE
SET EXECUTED = 'Y'
WHERE EMPLOYEE_UPDATE_ID = e_update.EMPLOYEE_UPDATE_ID ;
END LOOP;
-- run dynamic sql
END LOOP;
CLOSE employees;
END;
请帮忙。