Oracle触发器不会更新

时间:2016-07-28 17:22:49

标签: oracle oracle11g triggers

我已经运行此代码来创建此触发器,因为我需要使用插入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.

有人看到我出错了吗?

1 个答案:

答案 0 :(得分:6)

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

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块(如过程和函数)的工作方式相同。但我更喜欢重命名我的局部变量。