Debugando através de trigger – FORMAT_CALL_STACK
Olá Wilians !
Estou tentando rastrear um processo que está excluindo alguns dados. Faço isso através de uma trigger, mas não consigo capturar as informações que preciso. Pode me ajudar ?
Claiton
P.S. Meu banco é o 11g
É possível fazer um rastreamento, até que preciso, sobre o processo em execução que está excluindo um registro. E isso através de uma trigger.
Quem me conhece sabe que não gosto de limitar as possibilidades de se chegar a um resultado, portanto, não vou questionar se essa é a melhor maneira, mas vou demonstrar que é possível.
Para isso vamos utilizar a package DBMS_UTILITY. Mais precisamente, a função FORMAT_CALL_STACK.
Para quem não conhece, clique nos links acima para acessar a documentação da package.
Então vamos lá, primeiramente vamos ver o que a FORMAT_CALL_STACK retorna, utilizando o código abaixo:
DECLARE
v_stack VARCHAR2(32000);
BEGIN
v_stack := DBMS_UTILITY.format_call_stack;
DBMS_OUTPUT.put_line(v_stack);
END;
----- PL/SQL Call Stack -----
object line object
handle number name
0x60538f168 5 anonymous block
Veja que ele mostrou que foi executado um BLOCO ANÔNIMO.
Agora vamos criar uma PROCEDURE simples:
CREATE OR REPLACE PROCEDURE prc_test_call
IS
v_stack VARCHAR2(32000);
BEGIN
v_stack := DBMS_UTILITY.format_call_stack;
DBMS_OUTPUT.put_line(v_stack);
END prc_test_call;
Procedure PRC_TEST_CALL compiled
Vamos executá-la agora:
BEGIN
prc_test_call;
END;
PL/SQL procedure successfully completed.
----- PL/SQL Call Stack -----
object line object
handle number name
0x651489b28 5 procedure <OWNER>.PRC_TEST_CALL
0x6063b3918 2 anonymous block
Veja que o resultado demonstrou que um bloco anônimo foi executado, chamando a procedure PRC_TEST_CALL.
Agora iremos ao que interessa e vamos testar a nossa TRIGGER. Primeiro, criemos a TABELA de testes:
CREATE TABLE teste_trigger
(
codigo NUMBER
,descricao VARCHAR2(200)
)
/
Table TESTE_TRIGGER created.
Vamos inserir alguns dados:
INSERT INTO teste_trigger VALUES (1,'DESCRICAO -1')
/
INSERT INTO teste_trigger VALUES (2,'DESCRICAO -2')
/
INSERT INTO teste_trigger VALUES (3,'DESCRICAO -3')
/
COMMIT
/
Agora criemos a nossa TRIGGER:
CREATE OR REPLACE TRIGGER trg_teste_trigger
AFTER DELETE ON teste_trigger
FOR EACH ROW
BEGIN
prc_test_call;
END trg_teste_trigger;
Trigger TRG_TESTE_TRIGGER compiled
Agora vamos excluir um registro:
DELETE FROM teste_trigger
WHERE codigo = 3
/
1 row deleted.
----- PL/SQL Call Stack -----
object line object
handle number name
0x651489b28 5 procedure <OWNER>.PRC_TEST_CALL
0x65215cde0 2 <OWNER>.TRG_TESTE_TRIGGER
Veja que ao excluir via comando SQL, ele apenas mostra a disparada da TRIGGER e a execução da PROCEDURE.
Vamos fazer de um modo diferente agora:
BEGIN
DELETE FROM teste_trigger
WHERE codigo = 3;
END;
PL/SQL procedure successfully completed.
----- PL/SQL Call Stack -----
object line object
handle number name
0x651489b28 5 procedure <OWNER>.PRC_TEST_CALL
0x65215cde0 2 <OWNER>.TRG_TESTE_TRIGGER
0x652774178 2 anonymous block
Observe que agora ele informa que um BLOCO ANÔNIMO disparou a TRIGGER que chamou a PROCEDURE.
Vamos mudar mais uma vez:
CREATE OR REPLACE PROCEDURE prc_teste_delete
IS
BEGIN
DELETE FROM teste_trigger
WHERE codigo = 3;
END prc_teste_delete;
Procedure PRC_TESTE_DELETE compiled
BEGIN
prc_teste_delete;
END;
PL/SQL procedure successfully completed.
----- PL/SQL Call Stack -----
object line object
handle number name
0x651489b28 5 procedure <OWNER>.PRC_TEST_CALL
0x65215cde0 2 <OWNER>.TRG_TESTE_TRIGGER
0x6520850f0 4 procedure <OWNER>.PRC_TESTE_DELETE
0x604c14328 2 anonymous block
O BLOCO ANÔNIMO executou a PROCEDURE que disparou a TRIGGER que chamou a PROCEDURE. rs
Creio que da maneira que está, já atende as demandas solicitadas.
Eu faria um incremento, incluindo o nome do usuário que disparou o evento. Só que aí é com vocês agora. 😉
Até a próxima !
Referência