GPO ( Grupo de Profissionais Oracle )
A maior comunidade Oracle do Brasil !

Debugando através de trigger – FORMAT_CALL_STACK

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

Share

You may also like...

Deixe um comentário

O seu endereço de e-mail não será publicado.