Máte zde několik problémů, včetně:
IN_DATE
je deklarováno jako datum, takže jej nemusíte předávat přesTO_DATE()
.- Potřebujete pouze jednu smyčku kurzoru; pokud chcete zpracovat všechny aktualizace pro
employee_id
společně z nějakého důvodu můžete přidatorder by
doložka. - Dynamické SQL vůbec nepotřebujete; hodnoty z kurzoru můžete použít jako součást statické aktualizace SQL.
Takže jednoduchá verze s jedinou smyčkou může vypadat nějak takto:
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;
Toto je použití for update
a where current of
konstrukty pro zamknutí řádku, se kterým pracujete, a pro zjednodušení aktualizace; dokumentaci naleznete zde
.
Stojí za zmínku, že pokud buď effective_date
nebo p_date
má časovou složku, která se nebude shodovat. Pro p_date
je to nepravděpodobné , ale hůře se odhaduje pro effective_date
. Pokud ano, musíte buď trunc()
nebo použijte between
hledat řadu časů.