Oracle: Wie bestimme ich den neuen Namen eines Objekts in einem Auslöser "After Alter"?
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.
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;