【问题标题】:Simple IBM DB2 Trigger简单的 IBM DB2 触发器
【发布时间】:2018-04-11 15:35:34
【问题描述】:

我正在尝试在 DB2 (AS400) 中创建一个触发器,以便在另一个表上触发插入/删除时在表中插入/删除一行,但我需要使用有关触发器表的信息。

我想要的例子是这样的(表 1 和表 2 中的第 1 列在表 2 中相同且唯一):

CREATE TRIGGER MY_TRIGGER
AFTER INSERT OR DELETE ON DB1.TABLE1
BEGIN
      IF INSERTING 
              THEN INSERT INTO DB1.TABLE2 (Col1, Col2) VALUES (Db1.TABLE1.Col1, 0);
      ELSEIF DELETING
              THEN DELETE FROM Db1.TABLE2 WHERE Col1=TABLE1.Col1;      
      END IF;
END 

但这不起作用(它无法识别插入/删除语句中的TABLE1.Col1)。

它还会提示我一个错误(我猜),因为当在表 1 中插入第二行时它会创建一个重复的键。当Table2.Col1 已经存在时,如何避免错误(只是跳过插入)?

【问题讨论】:

  • 我看到了一些在同一个触发器上同时使用插入和删除的示例,但这是我的问题的次要问题。我想要一个检查重复项的工作插入示例。 (顺便说一句,我在发布之前已经查看了该链接)。

标签: triggers insert db2 db2-400


【解决方案1】:

尝试像这样添加相关名称:

CREATE TRIGGER MY_TRIGGER
AFTER INSERT OR DELETE ON DB1.TABLE1
REFERENCING OLD ROW AS OLD
            NEW ROW AS NEW
BEGIN
      IF INSERTING 
              THEN INSERT INTO DB1.TABLE2 (Col1, Col2) VALUES (NEW.Col1, 0);
      ELSEIF DELETING
              THEN DELETE FROM Db1.TABLE2 WHERE Col1=OLD.Col1;      
      END IF;
END

触发器可以访问行的旧图像和新图像。你需要告诉它使用哪个。顺便说一句,只有更新操作会同时填充旧图像和新图像。插入只提供新图像,删除只提供旧图像。有人可能认为 SQL 可以解决这个问题,但不,您仍然必须明确地告诉它。

编辑这是实际使用的最终触发器(来自 cmets,谢谢@MarçalTorroella)

CREATE TRIGGER MY_TRIGGER 
  AFTER INSERT OR DELETE ON DB1.TABLE1 
  REFERENCING OLD ROW AS OLD 
              NEW ROW AS NEW 
  FOR EACH ROW MODE DB2ROW
  BEGIN 
    DECLARE rowcnt INTEGER; 
    IF INSERTING THEN
      SELECT COUNT(*) 
        INTO rowcnt 
        FROM DB1.TABL2 
        WHERE Col1 = NEW.Col1; 
      IF rowcnt = 0 THEN 
        INSERT INTO DB1.TABLE2 (Col1, Col2) 
          VALUES (NEW.Col1, 0); 
      END IF;
    ELSEIF DELETING THEN 
      DELETE FROM Db1.TABLE2 
        WHERE Col1=OLD.Col1; 
    END IF; 
  END

【讨论】:

  • 那行得通。必须添加“FOR EACH ROW”,否则不允许我使用“引用”。现在我需要捕获(或避免)当将具有相同 ID 的第二行添加到表 1 但我不想插入表 2(它是表 2 中的唯一 ID)时它产生的异常。
  • 我认为这应该可行,但我每次都遇到错误(即使表 2 中不存在行)。 SQLCODE -407 SQLSTATE 23502 列或变量 Table2.Col1 中不允许有空值。我最后使用的代码是:
  • 对不起,我看不到如何在评论上发布代码(没有选项) CREATE TRIGGER MY_TRIGGER DECLARE rowcnt INTEGER;在 DB1.TABLE1 上插入或删除后,将旧行作为新行引用,如果插入则从 DB1.TABL2 中选择 COUNT(*) 到 rowcnt,其中 Col1 = NEW.Col1; IF rowcnt = 0 THEN INSERT INTO DB1.TABLE2 (Col1, Col2) VALUES (NEW.Col1, 0);万一; ELSEIF DELETING THEN DELETE FROM Db1.TABLE2 WHERE Col1=OLD.Col1;万一;结束
  • 没想到 REFERENCING 需要用空格分隔,当人们想同时捕捉新旧时,谢谢!
猜你喜欢
  • 2013-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多