正确而谨慎地设置MySQL触发器语法

时间:2015-04-22 16:10:49

标签: mysql triggers

我一直在做很多关于MySQL和触发器的新知识。我认为我理解这个概念,并且我意识到使用它们有很多可能的危险。但是我相信它们的有限使用对于我想要执行的功能是正确的。

我有9个表,分别对应9种不同的基于Web的Ajax引擎表单。我一直在努力研究这些问题,这是我第一次使用Ajax,而且我对它们感到满意。每当用户对他们填写的任何一种形式进行更改时,更改都会被Ajax回到数据库,并且他们会得到确认或错误响应。非常坦率的。每个表格各自的表格都有一个“status”字段,一个“lastModified”字段和一个我称之为“agRef”的字段,它有点像状态,但是在表单达到某个阶段之前是空的,进一步沿着这个过程。

我有一个名为“records”的附加表,其中列出了任何其他表中的所有条目,以便我们可以轻松查看已启动的表单,最后一次更改的时间以及它们具有的状态。所以这里我认为触发器部分应该工作,这样我就不必在每次交易时对我的php中的“记录”表进行更新。

“记录”表的设置如下:

`uaID` int(11) NOT NULL AUTO_INCREMENT,
`uID` int(11) NOT NULL,
`appNo` int(11) NOT NULL,
`applicationKey` varchar(8) NOT NULL,
`appID` int(11) DEFAULT NULL,
`applicationName` varchar(64) NOT NULL,
`agRef` varchar(32) DEFAULT NULL,
`status` varchar(32) NOT NULL,
`dateStarted` int(11) NOT NULL,
`lastModified` int(11) NOT NULL,

现在,所有这些字段都会在插入匹配条目的同时填充表单所连接的其他9个表中的任何一个表。其他9个表中的一个表的一个小例子如下所示:

`appID` int(11) NOT NULL AUTO_INCREMENT,
`uID` int(11) NOT NULL,
`uaID` int(11) NOT NULL,
`status` varchar(32) NOT NULL DEFAULT 'Data Acquisition',
`agRef` varchar(32) DEFAULT NULL,
`groupName` varchar(64) DEFAULT NULL,
`shortTitle` varchar(64) DEFAULT NULL,
`recipient` varchar(64) DEFAULT NULL,
`partOfValCh` varchar(64) DEFAULT NULL,
`sector` varchar(64) DEFAULT NULL,
`subSector` varchar(64) DEFAULT NULL,
`topic` varchar(64) DEFAULT NULL,
   <snip because this can go on for a lot of lines>
`dateStarted` int(11) NOT NULL,
`lastModified` int(11) NOT NULL,
两个表上的

agRef现在保持为null,appID在创建时最初在记录表上为空,但是一旦相应的条目进入第二个表,就会立即更新,其中它由自动增量生成然后调用回到我的记录表,在那里插入appID。

从任何数据表中改变的三件事是三个字段“status”,“agRef”,“lastModified”。

所以我正在尝试创建一个触发器,在每次更改/更新数据表后执行此操作,以便记录表中的数据一致且准确。

这是我第一次触发设置尝试:

DELIMITER $$
CREATE TRIGGER `dataTableOne_to_records_sync` AFTER UPDATE ON `dataTableOne`
FOR EACH ROW BEGIN
UPDATE records (agRef, status, lastModified) VALUES (NEW.agRef, NEW.status, NEW.lastModified) WHERE appID = OLD.appID;
END$$
DELIMITER ;

我试图通过phpmyadmin设置它,但它返回一个错误,告诉我在我的UPDATE行中有语法问题。我觉得这是WHERE部分的问题 - appID是将“记录”中的行与“dataTableOne”中正在更新/更改的行相关联的一个常见元素。如何正确设置?我的错误是否更严重,我是否冒着创造巨大混乱的风险,就像一个永无止境的循环?我第一次这样做有点偏执。提前感谢您的帮助和建议。

UPDATE 我现在尝试了一些其他的触发器尝试,但是虽然MySQL会接受它们作为有效的触发器语法,但它们似乎总是打破整个数据库功能。任何人都可以帮助我使用我的触发器语法来使其正常工作吗?在上面的演示表中,如果SECOND表完全更新,我希望触发器将三个字段复制到FIRST表中。我要复制的三个值是“status”,“agRef”和“lastModified”。

我最近的失败尝试是:

CREATE TRIGGER AIGltInq_sync AFTER INSERT ON app_AIGltInq
FOR EACH ROW
UPDATE records r
SET r.agRef        = NEW.agRef
  , r.status       = NEW.status
  , r.lastModified = NEW.lastModified
WHERE uaID = NEW.uaID;

2 个答案:

答案 0 :(得分:0)

我完全不熟悉UPDATE陈述的那种形式。

要更改行中列的值,我们通常会编写一个UPDATE语句,如下所示:

 UPDATE records r
    SET r.agRef        = NEW.agRef
      , r.status       = NEW.status
      , r.lastModified = NEW.lastModified
  WHERE r.appId        = OLD.appID

参考:https://dev.mysql.com/doc/refman/5.5/en/update.html

答案 1 :(得分:0)

问题撤回。触发器是最好避免的,因为它们往往造成比他们修复更多的破损!大多数建议倾向于使用您用于与DB通信的任何脚本语言来处理该功能。在我的例子中,这是PHP和PHP现在正在执行我希望通过使用触发器来缩短的所有功能。课?想要正确地完成工作时不要采取捷径。 :)