Oracle: Wie bestimme ich den neuen Namen eines Objekts in einem Auslöser "After Alter"?

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

  •  05-07-2019
  •  | 
  •  

Frage

Angenommen, ich habe eine AFTER ALTER Trigger auf meiner Oracle -Datenbank und ich benenne ein Datenbankobjekt um (ALTER ... RENAME TO ...). Wie bestimme ich innerhalb des Auslösers das? Neu Name des Datenbankobjekts? Es scheint, dass die ORA_DICT_OBJ_OWNER, ORA_DICT_OBJ_NAME und ORA_DICT_OBJ_TYPE Funktionen geben alle die zurück alt Werte des Datenbankobjekts.

Zum Beispiel:

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;

Angenommen, ich benenne eine Tabelle um:

ALTER TABLE USELESS_TABLE9 RENAME TO USELESS_TABLE10

Die Datenbank gibt dies aus:

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

Aktualisieren: Leider war die oben präsentierte Ausgabe falsch. Die Ausgabe wurde tatsächlich von a generiert BEFORE DDL Auslöser und an AFTER DDL Auslöser, den ich früher erstellt hatte, nicht bis zum BEFORE RENAME und AFTER RENAME löst aus. Ich werde weiterhin untersuchen, warum die BEFORE RENAME und AFTER RENAME Auslöser schießen nicht ...

Aktualisieren: Es scheint, dass die BEFORE RENAME und AFTER RENAME Auslöser weigern sich zu feuern, aber die BEFORE ALTER und AFTER ALTER Auslöser tun. Ich habe die Frage entsprechend aktualisiert.

War es hilfreich?

Lösung

ALTER RENAME Wird den Abzug nicht abfeuern, RENAME x TO y Wille.

Was Ihre Frage zu Namen vor und nachher betrifft, müssen Sie die DDL analysieren, um sie so abzurufen:

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;

Die regulären Ausdrücke könnten sicherlich klarer geschrieben werden, aber es funktioniert:

RENAME 
mktestx
TO                 mktesty;

Before: mktestx
After: mktesty

AKTUALISIEREN Um Ihre geänderte Frage zu berücksichtigen:

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;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top