动态评估Oracle Trigger中的伪记录(:OLD,:NEW)

时间:2015-01-27 18:54:03

标签: oracle

问题:我有一个客户可以添加列的表。根据客户的疯狂程度,此表可能包含数百列不同的数据类型。我需要针对此表部署一个AFTER UPDATE触发器,以便为另一个表中为已更改的每个列值插入一行。

示例:

  • Table_A,第1行:Key_Value = 1,Col1 = 123,Col2 =“foo”... Col n =“bar”
  • Table_B,第1行:Key_Value = 1,ColName =“Col1”,ColValue = 123
  • Table_B,第2行:Key_Value = 1,ColName =“Col2”,ColValue =“foo”
  • Table_B,第3行:Key_Value = 1,ColName =“Col n ”,ColValue =“bar”

由于我不知道他们可能创建哪些列,并且必须使用应用程序部署此触发器,因此我需要动态评估OLD vs NEW伪记录(if :new.columns[1] != :old.columns[1] then...)以查看已更改的内容并仅记录改变了列。我能够找到的唯一示例需要显式引用伪记录中的列(if :new.col1 != :old.col1 then...)。

问题:有没有办法在Oracle中执行此操作?

警告:不,这不是出于审计目的,因此我无法使用Oracle的内置审核。不,我们不会重写我们的应用程序,因为您知道如何更好地做到这一点,这是它需要更好或更差的工作方式。

欢迎任何有用的评论。所有的snarkey DBA驱动都没有。提前谢谢。

1 个答案:

答案 0 :(得分:4)

没有。您无法动态引用:new:old伪记录中的列。

您最接近的可能是编写动态生成整个触发器主体的代码,方法是查询数据字典并对伪记录中的列进行静态引用。但是,每次在表中添加或删除列时都需要运行该代码。通常,这将作为正常发布管理的一部分来完成。如果您说人们在不经过发布过程的情况下添加和删除此表中的列,您可以编写一个DDL触发器,通过dbms_job提交一个调用重建触发器的过程的作业。这将是很多动人的事情,当一些事情不可避免地出现问题时进行故障排除会很麻烦,但是如果你不愿意接受实现功能的其他方式,那么你将拥有复杂性和...一起生活。