【问题标题】:Oracle Trigger Doesn't UpdateOracle 触发器不更新
【发布时间】:2016-12-03 05:37:12
【问题描述】:

我已运行此代码来创建此触发器,因为我需要使用插入到 TABLE1 中的具有相同序列号的行的 UID 值来更新 TABLE2。

CREATE OR REPLACE TRIGGER TRIG_NAME BEFORE INSERT ON TABLE1 FOR EACH ROW
DECLARE
  seq NUMBER(10);
  uid CHAR(36);
  BEGIN
    seq  := :new.SEQ;
    uid  := :new.UID;
    UPDATE TABLE2 SET TABLE2.UID = uid WHERE TABLE2.SEQ = seq;
    DBMS_OUTPUT.put_line('UPDATE TABLE2 SET UID = '||uid||' WHERE SEQ = '||seq||';');
END;

触发器似乎创建没有问题,所以我

SET SERVEROUTPUT ON;

然后

INSERT INTO TABLE1 (SEQ, UID) VALUES (47, 'TEST_VALUE');

得到预期的输出

UPDATE TABLE2 SET UID = TEST_VALUE                            WHERE SEQ = 47;

因此,正确的值似乎进入了触发器。然后我通过运行检查 TABLE2

SELECT SEQ,UID FROM TABLE2 WHERE SEQ = 47;

得到

SEQ UID                                
--- ------------------------------------
47                                    
1 row selected.

有人知道我哪里出错了吗?

【问题讨论】:

  • 您是否进行了回滚,即您是否忘记提交?
  • 同一个会话。不过,为了确定,我后来尝试过运行 COMMIT。

标签: oracle oracle11g triggers


【解决方案1】:

如果这真的是你的代码,那么声明

UPDATE TABLE2 SET TABLE2.UID = uid WHERE TABLE2.SEQ = seq;

sequid 解析为table2 中的列,而不是同名的局部变量。因此,您正在更新table2 中的每一行并将uid 值设置为现有值。最简单的解决方案是重命名局部变量,使它们不会与任何标识符冲突。我会使用 l_ 前缀

  DECLARE
    l_seq NUMBER(10);
    l_uid CHAR(36);
  BEGIN
    l_seq := :new.SEQ;
    l_uid := :new.UID;
    UPDATE TABLE2 SET TABLE2.UID = l_uid WHERE TABLE2.SEQ = l_seq ;
    DBMS_OUTPUT.put_line('UPDATE TABLE2 SET UID = '||l_uid ||' WHERE SEQ = '||l_seq ||';');
  END;

我相信您也可以使用触发器名称限定sequid,以强制这些引用指向局部变量。从来没有尝试过使用触发器,但它的工作方式应该与它对其他命名的 PL/SQL 块(如过程和函数)的工作方式相同。但我更愿意重命名我的局部变量。

【讨论】:

    猜你喜欢
    • 2011-10-25
    • 2019-05-03
    • 2017-06-11
    • 1970-01-01
    • 2012-08-29
    • 2017-11-08
    • 2013-07-01
    • 2012-06-17
    • 1970-01-01
    相关资源
    最近更新 更多