ここには、次のようないくつかの問題があります。
-
IN_DATE
は日付として宣言されているため、TO_DATE()
に渡す必要はありません。 。 - 必要なカーソルループは1つだけです。
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
を使用しています およびwhere current of
作業中の行をロックし、更新を簡素化するための構成。ドキュメント
どちらかのeffective_date
の場合、注目に値します またはp_date
一致しない時間コンポーネントがあります。 p_date
の可能性は低いです 、ただしeffective_date
を推測するのは難しい 。もしそうなら、あなたはtrunc()
する必要があります または、between
を使用します 時間の範囲を探すために。