Pular para o conteúdo

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

Sergio Willians

Sergio Willians

Sergio Willians é o fundador do GPO (Grupo de Profissionais Oracle) e possui quase 30 anos de experiência em tecnologias Oracle, sendo especialista em desenvolvimento Forms/Reports, PL/SQL e EBS (E-Business Suite) nos módulos Receivables, Payables e General Ledger. Atualmente trabalha na Scania Latin America, onde se dedica à área de integração de dados com Confluent Kafka. Sua paixão é compartilhar conhecimento com a comunidade Oracle, contribuindo para o crescimento e a excelência da plataforma.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

plugins premium WordPress