1

我试图寻找这个问题的答案,但找不到任何有用的东西。要么没有,要么我的搜索能力受到打击。无论如何,这是我的情况:

我有一个案例,我有 2 个相同的表,Z_TEST 和 Z_TEST2。如果您愿意,可以将 Z_TEST2 称为审计表。

两者都有 2 列,ID(编号)和 CFIELD(CLOB)。Z_TEST 有一个触发器,它将插入或更新 Z_TEST2(实际上只有 CLOB 字段)。

场景一:

如果我在 Z_TEST 上创建以下触发器,这是一个正常的触发器,审计表也会更新:

CREATE OR REPLACE TRIGGER Z_TEST_TRIG


AFTER INSERT OR UPDATE ON Z_TEST
    FOR EACH ROW

Begin
    If inserting then
    Begin
        insert into Z_TEST2 values(:new.ID, :new.CFIELD);
    end;
  end if;

  if updating then
    begin
        update Z_TEST2 Set CFIELD = :new.CFIELD where ID = :new.id;
    end;
  end if;
End;

场景二:

如果我创建以下作为复合触发器的触发器并使用其“在每一行之后”块,则审计表的 CLOB 会更新为空值:

create or replace trigger Z_TEST_TRIG
FOR UPDATE OR INSERT ON Z_TEST
COMPOUND TRIGGER 

AFTER EACH ROW IS
Begin
    If inserting then
    Begin
        insert into Z_TEST2 values(:new.ID, :new.CFIELD);
    end;
  end if;

  if updating then

    begin
        update Z_TEST2 Set CFIELD = :new.CFIELD where ID = :new.id;
    end;
  end if;
END AFTER EACH ROW;

END Z_TEST_TRIG;

有谁知道为什么这适用于场景 1,但不适用于场景 2?我们的整个框架基于场景 2(复合触发器),我最近才遇到使用 CLOB 数据类型的需求,随之而来的是这个问题。

为什么会有差异,我的代码是否遗漏了什么?

4

2 回答 2

2

没有时间在这个问题上徘徊,我通过使用变量来解决它。

在声明部分声明一个 CLOB 变量,并在每行之前或之后将 :new.clob_field 的值分配给它,并在插入/更新语句中使用该变量而不是触发器中的 :new.clob_field解决了这个问题。

我遇到了很多与此作斗争的人的帖子(特别是复合触发器,而不是简单的触发器),所以我希望我花在这方面的时间可以帮助其他人并节省他们的时间。

如果有人遇到这篇文章并且知道为什么 :new.clob_field 在用于每行之前/之后的插入/更新语句时在复合触发器中失去其价值的原因,这对我的理智真的很有帮助。脑子里一直有这样的想法,总有一天会死去的……

我还将假设这也适用于 BLOB(如果这会导致问题)。

于 2013-06-10T07:28:12.803 回答
1

像这样的东西......你只需要添加更新子句

   CREATE OR REPLACE TRIGGER after_row_insert
    AFTER INSERT
    ON Z_TEST
    REFERENCING NEW AS NEW OLD AS OLD
    FOR EACH ROW
    Begin
     insert into Z_TEST2 values(:new.ID, :new.CFIELD);
    End;
于 2013-06-07T12:50:10.060 回答