【问题标题】:How to log old/new rows as XML in triggers如何在触发器中将旧/新行记录为 XML
【发布时间】:2016-08-10 15:31:25
【问题描述】:

当触发器无法成功时,我想将旧行和新行作为 XML 写入异常表。我习惯于使用通用的EXCEPTION WHEN OTHERS THEN 子句来注销失败,但我想不通的是必须将OLDNEW 伪行捕获(以便我可以记录)到XML 中。

好像

old_x := dbms_xmlgen.getxml('select * from OLD');

应该可以工作,但也许我错过了一些简单的东西。

【问题讨论】:

    标签: sql xml plsql triggers


    【解决方案1】:

    您无法从old 中进行选择,并且恐怕无法通用访问old 值-您必须一一指定old.empnoold.ename 等。

    Tom Kyte 展示了如何生成触发器来克服这个here on asktom.oracle.com

    【讨论】:

    • 以前从未尝试过选择旧/新,只是想用它来记录。假设太多了。
    【解决方案2】:

    阅读the fine document

    在行级别触发的触发器可以使用相关名称访问正在处理的行中的数据。默认的相关名称是 OLD、NEW 和 PARENT。

    OLD、NEW 和 PARENT 也称为 伪记录,因为它们具有记录结构,但允许在比记录更少的上下文中使用。伪记录的结构是 table_name%ROWTYPE,其中 table_name 是创建触发器的表的名称(对于 OLD 和 NEW)或父表的名称(对于 PARENT)。

    (伪记录还有其他限制在文档中明确提及,但未在此处引用。)

    除此之外,这些限制意味着不能使用伪记录,例如在insert statement extension

    因此,您可以对伪记录做的唯一事情就是一个接一个地引用它的字段。

    示例

    create table a (a number, b date);
    create table b (a number, b date);
    
    create or replace trigger a_trg 
    before insert on a
    for each row
    begin
      -- NEW pseudorecord is not a real record and therefore compilation will fail:
      -- PLS-00049: bad bind variable 'NEW'
      -- insert into b values :new;
    
      -- NEW pseudorecord fields have to be referenced one-by-one
      insert into b(a, b) values(:new.a, :new.b);
    end;
    /
    show errors
    
    insert into a values(1, sysdate);
    
    select * from a;
    select * from b;
    

    【讨论】:

    • @user272736 - 我承认口是心非,当我写这个问题时,我很确定这是不可能的,但我当然愿意感到惊讶 - 认为我不是唯一的人。当 FM 掩盖答案时,我不确定 RTFM 是否适用,例如,我不能 100% 确定“伪记录不能出现在 记录级操作中。”的真正含义是 RLO 在 oracle 或数据库世界中从未仔细定义过。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2020-07-07
    • 2014-02-09
    • 2012-05-12
    • 2020-11-01
    • 1970-01-01
    • 2014-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多