Bạn có một số vấn đề ở đây, bao gồm:
-
IN_DATE
được khai báo là một ngày, vì vậy bạn không cần phải chuyển nó quaTO_DATE()
. - Bạn chỉ cần một vòng lặp con trỏ; nếu bạn muốn xử lý tất cả các bản cập nhật cho
employee_id
vì một số lý do, bạn có thể thêm một đơn đặt hàngorder by
mệnh đề. - Bạn không cần SQL động; bạn có thể sử dụng các giá trị từ con trỏ như một phần của bản cập nhật SQL tĩnh.
Vì vậy, một phiên bản đơn giản với một vòng lặp có thể trông giống như sau:
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;
Điều này đang sử dụng for update
và where current of
cấu trúc để khóa hàng bạn đang làm việc và để đơn giản hóa việc cập nhật; xem tài liệu tại đây
.
Cần lưu ý rằng nếu một trong hai effective_date
hoặc p_date
có thành phần thời gian mà chúng sẽ không khớp. Nó không chắc cho p_date
, nhưng khó đoán hơn đối với effective_date
. Nếu có thì bạn cần phải trunc()
nó hoặc sử dụng between
để tìm kiếm một khoảng thời gian.