Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como criar e executar uma consulta dinâmica no procedimento armazenado oracle?


Você tem alguns problemas aqui, incluindo:
  • IN_DATE é declarado como uma data, então você não precisa passar por TO_DATE() .
  • Você só precisa de um loop de cursor; se você quiser processar todas as atualizações de um employee_id juntos, por algum motivo, você pode adicionar um order by cláusula.
  • Você não precisa de SQL dinâmico; você pode usar os valores do cursor como parte de uma atualização SQL estática.

Portanto, uma versão simples com um único loop pode ser algo como:
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;

Isso está usando o for update e where current of construções para bloquear a linha com a qual você está trabalhando e para simplificar a atualização; consulte a documentação aqui .

Vale a pena notar que, se effective_date ou p_date tem um componente de tempo que não corresponderá. É improvável para p_date , mas mais difícil de adivinhar para effective_date . Se isso acontecer, você precisará trunc() ou use between para procurar um intervalo de vezes.