【问题标题】:Setting up MySQL trigger syntax correctly and carefully正确、仔细地设置 MySQL 触发器语法
【发布时间】:2015-04-22 16:10:48
【问题描述】:

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

我有 9 个表,它们对应于 9 个不同的基于 Web 的 Ajax 引擎表单。作为我第一次使用 Ajax,我在这些方面付出了很多努力,我对它们相当满意。每次用户对他们填写的任何表单进行更改时,更改都会被 Ajaxed 回数据库,并且他们会得到确认或错误响应。非常坦率的。每个表单各自的表都有一个“状态”字段、一个“lastModified”字段和一个我称之为“agRef”的字段,它有点像状态,但在表单到达某个阶段之前为空,在流程中更进一步。

我有一个名为“记录”的附加表,其中列出了任何其他表中的所有条目,因此我们可以轻松查看哪些表单已启动,最后一次更改的时间以及它们的状态。所以这就是我认为触发器部分应该起作用的地方,这样我就不必在每笔交易中更新我的 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 暂时保持为空,记录表上的 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 会接受它们作为有效的触发器语法,但它们似乎总是会破坏整个 DB 功能。任何人都可以帮助我使用触发语法以使其正常工作吗?在上面的演示表中,如果 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;

【问题讨论】:

    标签: mysql triggers


    【解决方案1】:

    我完全不熟悉 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

    【讨论】:

    • 感谢 spencer7593。虽然用您的建议替换我的 UPDATE 现在被接受为 phpmyadmin 中的有效触发器,但它破坏了表单功能并且不执行所需的功能。我不知道为什么。
    【解决方案2】:

    问题已撤回。触发器是最好避免的,因为它们往往会导致比修复更多的破损!大多数建议倾向于使用您用来与数据库对话的任何脚本语言来处理函数。就我而言,这是 PHP,PHP 现在正在执行我希望通过使用触发器来实现的所有功能。课?想把工作做好时不要走捷径。 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-26
      • 1970-01-01
      • 1970-01-01
      • 2014-02-10
      • 2017-03-28
      • 1970-01-01
      • 1970-01-01
      • 2015-08-09
      相关资源
      最近更新 更多