Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment créer et exécuter une requête dynamique dans une procédure stockée oracle ?

Vous avez quelques problèmes ici, notamment :

  • IN_DATE est déclarée comme une date, vous n'avez donc pas besoin de la passer par TO_DATE() .
  • Vous n'avez besoin que d'une seule boucle de curseur ; si vous souhaitez traiter toutes les mises à jour pour un employee_id ensemble pour une raison quelconque, vous pouvez ajouter un order by clause.
  • Vous n'avez pas du tout besoin de SQL dynamique ; vous pouvez utiliser les valeurs du curseur dans le cadre d'une mise à jour SQL statique.

Ainsi, une version simple avec une seule boucle pourrait ressembler à :

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;

Ceci utilise le for update et where current of des constructions à la fois pour verrouiller la ligne avec laquelle vous travaillez et pour simplifier la mise à jour ; voir la documentation ici .

Il convient de noter que si soit effective_date ou p_date a une composante temporelle qu'ils ne correspondent pas. C'est peu probable pour p_date , mais plus difficile à deviner pour effective_date . Si c'est le cas, vous devez soit trunc() ou utilisez between pour rechercher une plage de temps.