Du har et par problemer her, herunder:
IN_DATE
er erklæret som en dato, så du behøver ikke passere den gennemTO_DATE()
.- Du behøver kun én markørløkke; hvis du vil behandle alle opdateringer for et
employee_id
sammen af en eller anden grund kan du tilføje enorder by
klausul. - Du behøver slet ikke dynamisk SQL; du kan bruge værdierne fra markøren som en del af en statisk SQL-opdatering.
Så en simpel version med en enkelt løkke kan se sådan ud:
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;
Dette bruger for update
og where current of
konstruktioner til både at låse den række du arbejder med og for at forenkle opdateringen; se dokumentationen her
.
Det er værd at bemærke, at hvis enten effective_date
eller p_date
har en tidskomponent, de ikke matcher. Det er usandsynligt for p_date
, men sværere at gætte for effective_date
. Hvis det gør det, skal du enten trunc()
det, eller brug between
at lede efter en række gange.