【问题标题】:How can we figure out that a column in my oracle table is being populated/updated by a trigger of another table?我们如何才能确定我的 oracle 表中的列正在由另一个表的触发器填充/更新?
【发布时间】:2013-07-19 20:09:37
【问题描述】:

考虑一个场景,其中有两个表“A”和“B”。

表“A”有一个触发器“Ta”[在我加入这个项目之前很久就写好了,因此我完全不知道触发器],它更新了表“B”中名为“colB”的列。

现在,由于我主要使用表“B”并且关心“colB”的获取方式,我不知道触发器“Ta”是否正在更新此列。

所以我的问题是,是否有直接的 oracle 查询/方法来查找一个表中的列是否被另一个表上运行的任何触发器更新?

提前感谢您在这方面对我进行教育。

问候 a.b

【问题讨论】:

  • 是什么阻止您查看触发器的代码并查看它是否更新了表 B?
  • 查看您最喜欢的数据库工具(我的是 Toad)中表 B 属性的“使用者”选项卡。

标签: sql database oracle plsql


【解决方案1】:

Oracle 细粒度依赖跟踪知道使用了哪些列。不幸的是,无法跟踪该依赖项是用于读取还是写入。并且没有默认的DBA_DEPENDENCY_COLUMNS 视图来查找此信息。

但幸运的是Rob van Wijk 创造了这样的观点。他的博客有更多信息,包括赠款和create view 声明,大约在页面的一半。

例子:

drop table a;
drop table b;

create table a(colA number);
create table b(colB number, read_only number, not_used number);

create or replace trigger Ta
after update or insert or delete on a
begin
    update b set colB = read_only;
end;
/

--What triggers are referencing B's columns?
select owner, name, type, referenced_column
from dba_dependency_columns
where referenced_owner = user
    and referenced_name = 'B'
    and type = 'TRIGGER';

OWNER    NAME  TYPE     REFERENCED_COLUMN
-----    ----  ----     -----------------
JHELLER  TA    TRIGGER  COLB
JHELLER  TA    TRIGGER  READ_ONLY

该视图使用了几个未记录的表和一些高级 SQL 功能。这种视图在生产服务器上不是一个好主意。但它可能比任何涉及解析 SQL 的解决方案准确得多。

【讨论】:

  • 感谢各位大师的热心帮助。欣赏这个:-)!
【解决方案2】:

简单示例:

create table table_a(
 id number primary key,
 val varchar2( 100 )
);

create table table_b(
 len number
);

insert into table_b values ( 0 );

set define off
create or replace trigger after_table_a
after insert on table_a for each row
begin
   UpDate 
     table_B
       set len = len + length( :new.val );
end;
/

insert into table_a values ( 1, 'Ala ma kota');
insert into table_a values ( 2, 'As to ali pies');
commit;

select * from table_b;

       LEN
----------
        25 



和查询:

select trigger_name, 
       regexp_substr( trigger_body, 'update\s+table_b',1,1,'i') update_command
from (
  select ut.trigger_name, 
         dbms_metadata.GET_DDL('TRIGGER', ut.trigger_name) trigger_body 
  from user_dependencies ud
  join user_triggers ut on ( ud.type = 'TRIGGER' 
                             and ut.trigger_name = ud.name 
                             and ut.table_name <> ud.referenced_name )
  where ud.referenced_name = 'TABLE_B'
)
where regexp_instr( trigger_body, 'update\s+table_b',1,1,0,'i') > 0 ;


TRIGGER_NAME  UPDATE_COMMAND
------------- ------------------ 
AFTER_TABLE_A UpDate
                table_B

【讨论】:

    【解决方案3】:
    SELECT *
    FROM 
        user_sources
    WHERE
        type = 'TRIGGER'
    AND UPPER(text) LIKE '%UPDATE A%';
    

    但如果查询分两行如:

    UPDATE
        A
    SET
       ...
    

    因为text 匹配对应对象中的给定行。

    【讨论】:

    • select * from user_source where ... and regexp_like(text,'update[^[:alnum:]]a','i'),或者,看看那个特定的触发器......
    • 他说他想假设他不知道触发器
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多