gpt4 book ai didi

Oracle:如何确定 "AFTER ALTER"触发器中对象的新名称?

转载 作者:行者123 更新时间:2023-12-04 15:05:15 24 4
gpt4 key购买 nike

假设我有一个 AFTER ALTER在我的 Oracle 数据库上触发,我重命名了一些数据库对象 ( ALTER ... RENAME TO ... )。在触发器内,我如何确定 新品 数据库对象的名称?看来ORA_DICT_OBJ_OWNER , ORA_DICT_OBJ_NAMEORA_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 DDL我之前创建的触发器, 不是 BEFORE RENAMEAFTER RENAME触发器。我会继续调查为什么 BEFORE RENAMEAFTER RENAME触发器没有触发...

更新:看来 BEFORE RENAMEAFTER RENAME触发器拒绝触发,但 BEFORE ALTERAFTER ALTER触发器做。我已相应地更新了问题。

最佳答案

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;

关于Oracle:如何确定 "AFTER ALTER"触发器中对象的新名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1809787/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com