Anda memiliki beberapa masalah di sini, termasuk:
IN_DATE
dideklarasikan sebagai tanggal, jadi Anda tidak perlu meneruskannya melaluiTO_DATE()
.- Anda hanya perlu satu lingkaran kursor; jika Anda ingin memproses semua pembaruan untuk
employee_id
bersama-sama untuk beberapa alasan Anda dapat menambahkanorder by
klausa. - Anda tidak memerlukan SQL dinamis sama sekali; Anda dapat menggunakan nilai dari kursor sebagai bagian dari pembaruan SQL statis.
Jadi versi sederhana dengan satu putaran mungkin terlihat seperti:
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;
Ini menggunakan for update
dan where current of
konstruksi untuk mengunci baris yang sedang Anda kerjakan dan untuk menyederhanakan pembaruan; lihat dokumentasi di sini
.
Perlu diperhatikan bahwa jika effective_date
atau p_date
memiliki komponen waktu yang tidak cocok. Tidak mungkin untuk p_date
, tetapi lebih sulit ditebak untuk effective_date
. Jika ya, maka Anda perlu trunc()
itu, atau gunakan between
untuk mencari rentang waktu.