Sie haben hier einige Probleme, darunter:
IN_DATE
wird als Datum deklariert, sodass Sie es nicht durchTO_DATE()
übergeben müssen .- Sie brauchen nur eine Cursorschleife; wenn Sie alle Aktualisierungen für eine
employee_id
verarbeiten möchten zusammen aus irgendeinem Grund können Sie einorder by
hinzufügen Klausel. - Sie brauchen überhaupt kein dynamisches SQL; Sie können die Werte aus dem Cursor als Teil eines statischen SQL-Updates verwenden.
Eine einfache Version mit einer einzigen Schleife könnte also etwa so aussehen:
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;
Dies verwendet den for update
und where current of
Konstrukte, um sowohl die Zeile zu sperren, mit der Sie arbeiten, als auch die Aktualisierung zu vereinfachen; siehe die Dokumentation hier
.
Es ist erwähnenswert, dass entweder effective_date
oder p_date
hat eine Zeitkomponente, die sie nicht abgleichen. Es ist unwahrscheinlich für p_date
, aber schwerer zu erraten für effective_date
. Wenn dies der Fall ist, müssen Sie entweder trunc()
ausführen it, oder verwenden Sie between
um nach einer Reihe von Zeiten zu suchen.