我需要在存储过程中动态创建和执行查询。
我有两个表user和user_updates。
员工表有 emp_id, username, division, product, region, title etc.
emp_id, username, division, product, region, title etc.
Employee_updates具有类似以下的列 emp_id, effective_date, column_name, new_value etc.
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;
请帮忙。
您在这里遇到一些问题,包括:
IN_DATE
TO_DATE()
employee_id
order by
因此,具有单个循环的简单版本可能类似于:
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 updateandwhere current of构造来锁定您正在使用的行并简化更新;请参阅此处的文档。
for update
where current of
值得一提的是,如果其中一个effective_date或p_date一个没有时间部分,它们将不匹配。这不太可能p_date,但更难猜测effective_date。如果确实如此,那么您要么需要trunc()它,要么用它between寻找一段时间。
effective_date
p_date
trunc()
between