在 'after update' 触发器中将值附加到 CLOB

Appending values to a CLOB in an 'after update' trigger

CREATE TABLE COPPER_TAN_META
(
   ID decimal(22,0) PRIMARY KEY,
   NOTES clob,
   ERROR varchar2(2000)
);
CREATE UNIQUE INDEX SYS_C0070016 ON COPPER_TAN_META(ID);

更新前

ID  ERROR   NOTES
20  <null>  27-APR-21 08.48.18 AM - XML is not a full-text article;

更新

update COPPER_TAN_META set error = 'trigger warning' where id = 20;

有了触发器,我想看这个:

ID  ERROR            NOTES
20  trigger warning 27-APR-21 08.48.18 AM - XML is not a full-text article; <timestamp> - trigger warning;

我的触发器不起作用:

CREATE OR REPLACE TRIGGER copper_error_appends_to_note
  AFTER UPDATE of error on COPPER_TAN_META
  for each row
begin
  IF :new.error is not null THEN
    :new.notes := :old.notes || localtimestamp(0) || ' - ' || :new.error || '; ';
  END IF;
end;
/
Error: ORA-04098: trigger 'B026.COPPER_ERROR_APPENDS_TO_NOTE' is invalid and failed re-validation

使用普通的更新语句就可以正常工作,比如

update copper_tan_meta
set notes = notes || localtimestamp(0) || ' - ' || :fileError || '; ' 
where id = :tanMetaId

我是 运行 SQuirreL SQL 客户端版本 3.5.3

  • new 值无法更改 AFTER 触发器类型,但可以更改 BEFORE
  • 不带参数的
  • localtimestamp 可以在直接连接中使用,但是带 precision 参数的 localtimestamp 可以在 SQL 中使用,例如 localtimestamp(0)声明。

因此,将代码块重写为

CREATE OR REPLACE TRIGGER copper_error_appends_to_note
  BEFORE UPDATE OF ERROR ON copper_tan_meta
  FOR EACH ROW
DECLARE    
    ts TIMESTAMP;
BEGIN
  SELECT localtimestamp(0) INTO ts FROM dual;
  IF :new.error IS NOT NULL THEN
    :new.notes := :old.notes || ts || ' - ' || :new.error || '; ';
  END IF;
END;
/