No Oracle, uma transação autônoma pode confirmar ou reverter os dados na mesma sessão sem confirmar ou reverter na transação principal. A instrução PRAGMA (diretiva do compilador) é usada para definir transações autônomas no Oracle. Veja a seguir um exemplo de transação autônoma do Oracle.
Sintaxe para definir transações autônomas no Oracle
PRAGMA AUTONOMOUS_TRANSACTION; /* in the declaration section of PL/SQL Block */
Exemplo de procedimento armazenado do Oracle para transação autônoma
O seguinte procedimento armazenado do Oracle para a transação autônoma é registrar os erros ocorridos em qualquer programa PL/SQL (Procedimentos, pacotes ou funções, etc.). Ele inserirá as informações de erro na tabela error_log e confirmará os dados sem afetar nenhuma transação principal em nenhum programa PL/SQL. Você pode chamar esse procedimento de qualquer programa PL/SQL para registrar as informações de erro. Abaixo vou te mostrar como. Crie os seguintes objetos para testar em seu sistema:
Criar tabela Error_Log
CREATE TABLE error_log ( error_code VARCHAR2 (100), error_msg VARCHAR2 (4000), date_occurred DATE, plsql_program_ref VARCHAR2 (100) ) /
Procedimento armazenado do Oracle para transações autônomas para registrar erros
O procedimento abaixo leva três parâmetros, que você precisa passar no momento de chamar o procedimento de outros procedimentos armazenados ou funções no momento do erro.
CREATE OR REPLACE PROCEDURE prc_log_errors (v_error_code IN VARCHAR2, v_error_msg IN VARCHAR2, v_plsql_program IN VARCHAR2) AS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO error_log (ERROR_CODE, ERROR_MSG, DATE_OCCURRED, PLSQL_PROGRAM_REF) VALUES (v_error_code, v_error_msg, SYSDATE, v_plsql_program); COMMIT; END; /
Agora você pode chamar o procedimento armazenado prc_log_errors da seção de tratamento de exceção de outro programa PL/SQL para registrar as informações de erro. Aqui está um exemplo:
Criar tabela test_data
CREATE TABLE test_data (some_data VARCHAR2 (100)) /
Criar função fnc_test
A função a seguir irá inserir alguns dados no test_data table, e depois disso, vai gerar o erro porque está dividindo por 0 na próxima linha. Em caso de erro, na seção de exceção, está chamando o procedimento prc_log_errors para registrar o erro. Se a função for executada sem erro, ela retornará TRUE senão retornará FALSE. No caso abaixo, retornará o FALSE após registrar o erro.
CREATE OR REPLACE FUNCTION fnc_test RETURN BOOLEAN IS n NUMBER; BEGIN INSERT INTO test_data VALUES ('abc'); /* generate error */ n := 2 / 0; RETURN TRUE; EXCEPTION WHEN OTHERS THEN prc_log_errors (TO_CHAR (SQLCODE), SQLERRM, 'FNC_TEST'); RETURN FALSE; END fnc_test; /
Teste
Chame a função acima fnc_test .
BEGIN IF fnc_test THEN COMMIT; ELSE ROLLBACK; END IF; EXCEPTION WHEN OTHERS THEN ROLLBACK; END; /
Mesmo ele está revertendo em caso de falha, mas ainda assim, os dados serão salvos na tabela error_log, porque o procedimento prc_log_errors está usando PRAGMA AUTONOMOUS_TRANSACTION .
Verifique a tabela test_data, não deve ter registros.
SELECT * FROM test_data;
Saída
no rows selected.
Verificar dados na tabela error_log
SELECT * FROM error_log;
Saída
ERROR_CODE ERROR_MSG DATE_OCCURRED PLSQL_PROGRAM_REF -1476 ORA-01476: divisor is equal to zero 27/03/2019 15:43:12 FNC_TEST
Veja também:
- Exemplo de coleta em massa Oracle PL/SQL com exceção de salvamento