【发布时间】:2016-08-10 15:31:25
【问题描述】:
当触发器无法成功时,我想将旧行和新行作为 XML 写入异常表。我习惯于使用通用的EXCEPTION WHEN OTHERS THEN 子句来注销失败,但我想不通的是必须将OLD 和NEW 伪行捕获(以便我可以记录)到XML 中。
好像
old_x := dbms_xmlgen.getxml('select * from OLD');
应该可以工作,但也许我错过了一些简单的东西。
【问题讨论】:
当触发器无法成功时,我想将旧行和新行作为 XML 写入异常表。我习惯于使用通用的EXCEPTION WHEN OTHERS THEN 子句来注销失败,但我想不通的是必须将OLD 和NEW 伪行捕获(以便我可以记录)到XML 中。
好像
old_x := dbms_xmlgen.getxml('select * from OLD');
应该可以工作,但也许我错过了一些简单的东西。
【问题讨论】:
您无法从old 中进行选择,并且恐怕无法通用访问old 值-您必须一一指定old.empno、old.ename 等。
Tom Kyte 展示了如何生成触发器来克服这个here on asktom.oracle.com。
【讨论】:
在行级别触发的触发器可以使用相关名称访问正在处理的行中的数据。默认的相关名称是 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;
【讨论】: