如何创建触发器触发器自引用触发器..是 啊



我有一个MySQL数据库。。。有趣的架构和复杂的注册过程。有几个程序表在更新、插入或删除时需要在历史注册表上插入行。我已经在每个表(大约30个不同的表)上使用触发器,并在所有表上迭代以下内容:

DROP TRIGGER IF EXISTS programTable_afterinsert;$$
CREATE TRIGGER programTable_afterinsert AFTER INSERT ON programTable
FOR EACH ROW
    BEGIN
        IF NEW.Enrolled = 1
            THEN
                INSERT INTO enrollment (ID, Action, Date_Updated, User, Program, Reason, Action_Date)
                    VALUES (NEW.ID, 'Enrolled', NOW(), 'programUser', 'programName', 'Enrolled in program', NOW());
        ELSEIF NEW.Enrolled = 0
            THEN
                INSERT INTO enrollment (Member_ID, Action, Date_Updated, User, Program, Reason, Action_Date)
                    VALUES (NEW.ID, 'Disenrolled', NOW(), 'programUser', 'programName', 'Disenrolled from program', NOW());
        END IF;
    END;$$
DROP TRIGGER IF EXISTS programTable_afterupdate;$$
CREATE TRIGGER programTable_afterupdate AFTER UPDATE ON programTable
FOR EACH ROW
    BEGIN
        IF NEW.Enrolled = 1
            THEN 
                INSERT INTO enrollment (ID, Action, Date_Updated, User, Program, Reason, Action_Date)
                    VALUES (NEW.Member_ID, 'Enrolled', NOW(), 'programUser', 'programName', 'Enrolled in program', NOW());
        ELSEIF NEW.Enrolled = 0
            THEN 
                INSERT INTO enrollment (ID, Action, Date_Updated, User, Program, Reason, Action_Date)
                    VALUES (NEW.ID, 'Disenrolled', NOW(), 'programUser', 'programName', 'Disenrolled from program', NOW());
        END IF;
    END;$$
DROP TRIGGER IF EXISTS programTable_afterdelete;$$
CREATE TRIGGER programTable_afterdelete AFTER DELETE ON programTable
FOR EACH ROW
    BEGIN
        IF OLD.Enrolled = 1
            THEN 
                INSERT INTO enrollment (ID, Action, Date_Updated, User, Program, Reason, Action_Date)
                    VALUES (OLD.ID, 'Disenrolled', NOW(), 'programUser', 'programName', 'Removed from program', NOW());
        END IF;
    END;$$

可以使用以下内容创建精简版的注册和计划表:

delimiter $$
CREATE TABLE `programTable1` (
  `ID` varchar(15) NOT NULL,
  `Enrolled` tinyint(3) unsigned NOT NULL,
  `Referral_Date` datetime NOT NULL,
  `Referral_Source` varchar(255)
);$$
CREATE TABLE `programTable2` (
  `ID` varchar(15) NOT NULL,
  `Enrolled` tinyint(3) unsigned NOT NULL,
  `Referral_Date` datetime NOT NULL,
  `Referral_Source` varchar(255)
);$$
CREATE TABLE `enrollment` (
  `ID` varchar(15) NOT NULL,
  `Action` varchar(12) NOT NULL,
  `Date_Updated` timestamp NOT NULL,
  `User` varchar(12) default NULL,
  `Program` varchar(25) NOT NULL,
  `Notes` varchar(100) default NULL,
  `Reason` varchar(45) default NULL,
  `Action_Date` datetime NOT NULL
);$$

我遇到的障碍是,当程序表被修改或添加了一行时,注册表需要更新程序表的注册。这意味着,如果有人在程序表上注册,他们需要在注册表上有一个条目来执行该操作;如果有人通过登记表登记,则需要在该行适用的程序表上将其更新为已登记或已取消登记。

主要的问题是,有两种不同的来源的人报名参加这些项目。

就像我说的,错综复杂。我知道这个应用程序的体系结构不是最好的,但它不是可以改变的。

欢迎有任何想法!如果有人有问题或需要澄清,请告诉我。我已经做了一段时间了,所以我知道我可能会因为太熟悉它而把一些东西排除在等式之外。

创建更新彼此表的触发器没有问题——只要触发器不继续在无限循环中来回插入即可。

您需要确保触发器执行的INSERT将一行插入到另一个表中,这将导致而不是的交互操作。

我在最近的另一个问题中写了一个例子:镜像表:触发器、死锁和隐式提交

最新更新