在更新后触发器上获取更新列名的有效方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在更新后触发器上获取更新列名的有效方法相关的知识,希望对你有一定的参考价值。

我想出了以下触发器来提取执行表行更新语句时更新的所有列名...

但问题是如果有更多列(至少100列),性能/效率就会受到关注

示例触发器代码:

set define off;
create or replace TRIGGER TEST_TRIGG
AFTER UPDATE ON A_AAA
FOR EACH ROW
DECLARE
    mytable varchar2(32) := 'A_AAA';
    mycolumn varchar2(32);
    updatedcols varchar2(3000);

    cursor s1 (mytable varchar2) is 
        select column_name from user_tab_columns where table_name = mytable;
begin

        open s1 (mytable);

        loop
            fetch s1 into mycolumn;
            exit when s1%NOTFOUND;

            IF UPDATING( mycolumn ) THEN
                updatedcols := updatedcols || ',' || mycolumn;
            END IF;

        end loop;
        close s1;
        --do a few things with the list of updated columns
    dbms_output.put_line('updated cols ' || updatedcols);
end;
/

有没有其他方法可以获得列表?

也许使用v $ tables(v $ transaction或类似的东西)?

答案

不,这是qazxsw poi获得qazxsw poi专栏的最佳方式

并且您可以使用这样的隐式游标更改代码,它会更快一点

UPDATED
另一答案

面对类似的任务,我们最终编写了一个pl / sql过程,列出了表的列并为我们生成了完整的触发器体,静态代码引用了UPDATING()set define off; create or replace TRIGGER TEST_TRIGG AFTER UPDATE ON A_AAA FOR EACH ROW DECLARE updatedcols varchar2(3000); begin for r in (select column_name from user_tab_columns where table_name ='A_AAA') loop IF UPDATING(r.column_name) THEN updatedcols := updatedcols || ',' || r.column_name; END IF; end loop; dbms_output.put_line('updated cols ' || updatedcols); end; / 。这种触发器的执行应该更快(尽管我们没有比较)。

但是,缺点是当您稍后向表中添加新列时,很容易忘记更新触发器主体。它可能以某种方式通过监视工作或其他方式进行管理,但是现在它对我们有用。

附:我很好奇:new.col功能做了什么,现在检查了一下。我发现如果列存在于:old.col语句中它返回true,即使列的值实际上没有改变(updating('COL')等于update)。如果通过类似Java Hibernate库的方式更新表,则可能会生成不需要的历史记录,这些库(默认情况下)始终指定它生成的更新语句中的所有列。在这种情况下,您可能希望实际比较触发器主体内部的值,并仅在新值与旧值不同时插入历史记录。

以上是关于在更新后触发器上获取更新列名的有效方法的主要内容,如果未能解决你的问题,请参考以下文章

无论控件如何,在表单上的任何控件更新后有啥方法可以触发事件?

如何在 SQL Server 2008 上创建插入更新触发器

更新后更新触发器逻辑

如何在 MySQL 中获取特定表的主键“列名”

小程序各种功能代码片段整理---持续更新

如何检查刚体是否在移动?