Oracle: comment déterminer le NOUVEAU nom d'un objet dans un fichier & # 8220; AFTER ALTER & # 8221; déclencheur?

StackOverflow https://stackoverflow.com/questions/1809787

  •  05-07-2019
  •  | 
  •  

Question

Supposons que j'ai un déclencheur AFTER ALTER sur ma base de données Oracle et que je renomme un objet de base de données ( ALTER ... RENAME TO ... ). Dans le déclencheur, comment puis-je déterminer le nouveau nom de l'objet de base de données? Il semble que les fonctions ORA_DICT_OBJ_OWNER , ORA_DICT_OBJ_NAME et ORA_DICT_OBJ_TYPE renvoient toutes les valeurs anciennes de l'objet de base de données.

Par exemple:

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;

Supposons que je renomme une table:

ALTER TABLE USELESS_TABLE9 RENAME TO USELESS_TABLE10

La base de données génère ceci:

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

Mise à jour: Malheureusement, le résultat présenté ci-dessus était incorrect. La sortie était en fait générée par un déclencheur BEFORE DDL et un déclencheur AFTER DDL que j'avais créé précédemment, pas par le BEFORE RENAME et les déclencheurs AFTER RENAME . Je continuerai à rechercher pourquoi les déclencheurs BEFORE RENAME et AFTER RENAME ne se déclenchent pas ...

Mise à jour: Il semble que les déclencheurs BEFORE RENAME et AFTER RENAME refusent de se déclencher, mais le BEFORE ALTER et les déclencheurs AFTER ALTER le font. J'ai mis à jour la question en conséquence.

Était-ce utile?

La solution

ALTER RENAME ne déclenchera pas le déclencheur, RENAME x TO y le fera.

En ce qui concerne votre question sur les noms avant et après, je pense que vous devrez analyser le DDL pour les récupérer, comme suit:

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;

Les expressions régulières pourraient certainement être écrites plus clairement, mais cela fonctionne:

RENAME 
mktestx
TO                 mktesty;

Before: mktestx
After: mktesty

METTRE À JOUR pour répondre à la question modifiée:

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;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top