【问题标题】:Before update oracle trigger problem [PL/SQL]更新oracle之前触发问题[PL/SQL]
【发布时间】:2021-04-22 23:44:03
【问题描述】:

表:

CREATE TABLE EXAMPLE1 (column1 integer, column2 integer, column3 integer);

插入:

INSERT INTO EXAMPLE1 VALUES (1,11,111);

触发器:

create or replace TRIGGER trigger_name
BEFORE UPDATE OF COLUMN1 ON EXAMPLE1
FOR EACH ROW
BEGIN
    RAISE_APPLICATION_ERROR(-20000, 'You can't directly update this column.');
END;

更新:

UPDATE EXAMPLE1 SET COLUMN1 = 2 WHERE COLUMN2 = 11;

所以,当我尝试更新 column1 (column1 = 2) 触发器时,应该执行并告诉我不能直接更改该列,但是如果我执行这样的查询:

UPDATE EXAMPLE1 SET column1 = 1, column2 = 22 where column3 = 111;

我的意思是我也发送 column1 = 1(column1 等于 1),所以值没有变化,它应该更新表,因为我只更改 column2,column1 保持不变,等于 1。

【问题讨论】:

  • 无论新值是什么,您仍在更新该列,在您的触发器中,您必须检查该值是否正在更改
  • @eshirvana 有没有机会给我发一个代码,我是新手:/

标签: sql database oracle plsql triggers


【解决方案1】:

无论新值是什么,您仍在更新列,在您的触发器中,您必须检查该值是否正在更改:

CREATE OR REPLACE TRIGGER trigger_name
BEFORE UPDATE OF COLUMN1 ON EXAMPLE1
FOR EACH ROW
BEGIN
    IF DECODE(:new.column1, :old.column1, 1, 0) = 0 THEN
      RAISE_APPLICATION_ERROR(-20000, 'You can''t directly update this column.')
    END IF
END;

【讨论】:

  • 您还需要处理null - 如果其中一个值(旧的或新的)或两者都是null,该怎么办?
  • Err...nvl 方法很常见,但错误。如果新值为 1 但旧值为 null 怎么办?您的条件将允许更新,因为它看到 null 与 1 相同。您可以对其进行修改,以便使用不同的值而不是 1(数据中不可能的值),但即使这样也是一种不好的做法.更常见的写法是if decode(:new.column1, :old.column1, 1, 0) = 0 then... - decode 经常被使用,因为它认为null 等于null(类似于你在group by 中的内容,例如,与大多数其他SQL 不同) .
  • 不,我尝试过仍然有问题,如果我更新所有其他列,它将更新,但如果我更改受限列,它不会给我来自 raise_application 的回复消息。该列是一个外键 btw (使用短路键),因此该列正在从其他表更新,但由此受到限制。
【解决方案2】:

使用when子句如下:

CREATE OR REPLACE TRIGGER trigger_name
BEFORE UPDATE OF COLUMN1 ON EXAMPLE1
FOR EACH ROW
WHEN ( NEW.COLUMN1 <> OLD.COLUMN1 
       OR NOT (NEW.COLUMN1 IS NULL AND OLD.COLUMN1 IS NULL)
      ) 
BEGIN
      RAISE_APPLICATION_ERROR(-20000, 'You can''t directly update this column.');
END;
/

【讨论】:

    猜你喜欢
    • 2011-07-29
    • 1970-01-01
    • 2016-06-11
    • 1970-01-01
    • 2012-11-14
    • 2012-04-20
    • 2011-08-06
    • 1970-01-01
    • 2017-09-14
    相关资源
    最近更新 更多