Oracle : "After Alter"트리거에서 새 이름의 새 이름을 어떻게 결정합니까?
문제
내가 있다고 가정 해 AFTER ALTER
내 Oracle 데이터베이스를 트리거하고 일부 데이터베이스 객체를 바꾸는 (ALTER ... RENAME TO ...
). 방아쇠 내에서 어떻게 결정합니까 새로운 데이터베이스 개체의 이름? 그게 보인다 ORA_DICT_OBJ_OWNER
, ORA_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
데이터베이스는 이것을 출력합니다.
Before alter: DEVELOPER.USELESS_TABLE9 (TABLE) After alter: DEVELOPER.USELESS_TABLE9 (TABLE)
업데이트: 불행히도, 위에서 제시 한 출력이 잘못되었습니다. 출력은 실제로 a BEFORE DDL
트리거와 an AFTER DDL
내가 이전에 만든 트리거, ~ 아니다 에 의해 BEFORE RENAME
그리고 AFTER RENAME
트리거. 나는 왜 그런지 계속 조사 할 것입니다 BEFORE RENAME
그리고 AFTER RENAME
트리거가 발사되지 않습니다 ...
업데이트: 그게 보인다 BEFORE RENAME
그리고 AFTER RENAME
트리거는 발사를 거부하지만 BEFORE ALTER
그리고 AFTER ALTER
트리거합니다. 그에 따라 질문을 업데이트했습니다.
해결책
ALTER RENAME
방아쇠를 발사하지 않을 것입니다. RENAME x TO y
할 것이다.
전후에 이름에 대한 질문에 관해서는 DDL을 검색하기 위해 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;