6

Oracleデータベースにトリガーがあり、AFTER ALTERデータベースオブジェクトの名前を変更するとします(ALTER ... RENAME TO ...)。トリガー内で、データベースオブジェクトの新しい名前を確認するにはどうすればよいですか?ORA_DICT_OBJ_OWNERORA_DICT_OBJ_NAMEおよび関数はすべて、データベースオブジェクトの古いORA_DICT_OBJ_TYPE値を返すようです。

例えば:

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;

テーブルの名前を変更するとします。

ALTER TABLE USELESS_TABLE9 RENAME TO USELESS_TABLE10

データベースはこれを出力します:

変更前:DEVELOPER.USELESS_TABLE9(TABLE)
変更後:DEVELOPER.USELESS_TABLE9(TABLE)

更新:残念ながら、上記の出力は正しくありませんでした。出力は、実際には、トリガーとトリガーではなく、以前に作成したトリガーとトリガーによって生成されいましBEFORE DDLた。とトリガーが起動しない理由を引き続き調査します...AFTER DDLBEFORE RENAMEAFTER RENAMEBEFORE RENAMEAFTER RENAME

更新:とトリガーは発砲を拒否しているように見えますが、BEFORE RENAMEとトリガーは発砲します。それに応じて質問を更新しました。AFTER RENAMEBEFORE ALTERAFTER ALTER

4

1 に答える 1

6

ALTER RENAMEトリガーを起動しません、しRENAME x TO yます。

前後の名前に関する質問については、次のようにDDLを解析して取得する必要があると思います。

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;

正規表現は確かにより明確に書くことができますが、それは機能します:

RENAME 
mktestx
TO                 mktesty;

Before: mktestx
After: mktesty

更新変更された質問に対応するには:

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;
于 2009-11-27T17:55:25.833 に答える