Pergunta

Suponha que eu tenho um AFTER ALTER Trigger no meu banco de dados Oracle e renomei algum objeto de banco de dados (ALTER ... RENAME TO ...). Dentro do gatilho, como faço para determinar o novo Nome do objeto de banco de dados? Parece que o ORA_DICT_OBJ_OWNER, ORA_DICT_OBJ_NAME e ORA_DICT_OBJ_TYPE Funções retornam o velho valores do objeto de banco de dados.

Por exemplo:

CREATE OR REPLACE TRIGGER ADAM_BEFORE_AFTER BEFORE ALTER ON DATABASE
BEGIN
  DBMS_OUTPUT.put_line('Before alter: ' || ora_dict_obj_owner || '.' || ora_dict_obj_name || ' (' || ora_dict_obj_type || ')');
END;

CREATE OR REPLACE TRIGGER ADAM_AFTER_ALTER AFTER ALTER ON DATABASE
BEGIN
  DBMS_OUTPUT.put_line('After alter: ' || ora_dict_obj_owner || '.' || ora_dict_obj_name || ' (' || ora_dict_obj_type || ')');
END;

Suponha que eu renomeei uma tabela:

ALTER TABLE USELESS_TABLE9 RENAME TO USELESS_TABLE10

O banco de dados gera isto:

Before alter: DEVELOPER.USELESS_TABLE9 (TABLE)
After alter: DEVELOPER.USELESS_TABLE9 (TABLE)

Atualizar: Infelizmente, a saída que apresentei acima estava incorreta. A saída estava realmente sendo gerada por um BEFORE DDL gatilho e um AFTER DDL gatilho que eu havia criado anteriormente, não pelo BEFORE RENAME e AFTER RENAME gatilhos. Vou continuar investigando por que o BEFORE RENAME e AFTER RENAME Os gatilhos não estão disparando ...

Atualizar: Parece que o BEFORE RENAME e AFTER RENAME gatilhos se recusam a disparar, mas o BEFORE ALTER e AFTER ALTER gatilhos fazem. Eu atualizei a pergunta de acordo.

Foi útil?

Solução

ALTER RENAME não vai disparar o gatilho, RENAME x TO y vai.

Quanto à sua pergunta sobre nomes antes e depois, acho que você terá que analisar o DDL para recuperá -los, assim:

CREATE OR REPLACE TRIGGER MK_BEFORE_RENAME BEFORE RENAME ON SCHEMA 
DECLARE 
  sql_text ora_name_list_t;
  v_stmt VARCHAR2(2000);
  n PLS_INTEGER; 
BEGIN  
  n := ora_sql_txt(sql_text);
  FOR i IN 1..n LOOP
   v_stmt := v_stmt || sql_text(i);
  END LOOP;

  Dbms_Output.Put_Line( 'Before: ' || regexp_replace( v_stmt, 'rename[[:space:]]+([a-z0-9_]+)[[:space:]]+to.*', '\1', 1, 1, 'i' ) );
  Dbms_Output.Put_Line( 'After: ' || regexp_replace( v_stmt, 'rename[[:space:]]+.*[[:space:]]+to[[:space:]]+([a-z0-9_]+)', '\1', 1, 1, 'i' ) );
END;

As expressões regulares certamente podem ser escritas com mais clareza, mas funciona:

RENAME 
mktestx
TO                 mktesty;

Before: mktestx
After: mktesty

ATUALIZAR Para acomodar sua pergunta alterada:

CREATE OR REPLACE TRIGGER MK_AFTER_ALTER AFTER ALTER ON SCHEMA 
DECLARE 
  sql_text ora_name_list_t;
  v_stmt VARCHAR2(2000);
  n PLS_INTEGER; 
BEGIN  
  n := ora_sql_txt(sql_text);
  FOR i IN 1..n LOOP
   v_stmt := v_stmt || sql_text(i);
  END LOOP;

  Dbms_Output.Put_Line( 'Before: ' || regexp_replace( v_stmt, 'alter[[:space:]]+table[[:space:]]+([a-z0-9_]+)[[:space:]]+rename[[:space:]]+to.*', '\1', 1, 1, 'i' ) );
  Dbms_Output.Put_Line( 'After: ' || regexp_replace( v_stmt, 'alter[[:space:]]+table[[:space:]]+.*to[[:space:]]+([a-z0-9_]+)', '\1', 1, 1, 'i' ) );
END;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top