【问题标题】:MySQL - Trigger error on row updateMySQL - 行更新时触发错误
【发布时间】:2013-08-02 12:07:37
【问题描述】:

我正在尝试实现一个触发器以在行更新时自动增加一个字段。每次更新 PERSON 表中的现有行时,我希望一致性版本自动增加一。

我的桌子:

CREATE TABLE PERSON (
id INT NOT NULL AUTO_INCREMENT,
consistency_version INT NOT NULL DEFAULT 0,
name    CHAR (100) NOT NULL,
);

和触发器:

CREATE TRIGGER consistency_version_trigger BEFORE UPDATE ON PERSON
FOR EACH ROW SET NEW.VERSION = @VERSION+1 

当我对表中的一行执行更新语句时,我希望一致性版本增加一

但我收到以下错误:

Column "consistency_version" cannot be null

谁能告诉我我做错了什么?我认为@VERSION 为空。如何将此值设置为正在更新的当前行的版本?

【问题讨论】:

    标签: mysql sql triggers


    【解决方案1】:

    我的最佳猜测是“@version”返回 NULL。这会导致@version + 1 导致为空,然后尝试将不可为空的一致性_版本列设置为空,从而导致错误。

    您是否尝试过使用 OLD 代替?

    CREATE TRIGGER consistency_version_trigger BEFORE UPDATE ON PERSON
    FOR EACH ROW SET NEW.VERSION = OLD.VERSION+1

    【讨论】:

      【解决方案2】:

      @VERSION 是一个会话变量。它存在并且仅在创建它的会话期间可见。所以你基本上是在说SET NEW.VERSION = NULL + 1 这是NULL。

      假设由于某种原因内置的自动增量功能不符合您的需求:

      要创建全局自动递增值,您需要使用表格。 像这样创建一个表:

      CREATE TABLE `consistency_version` (
          `consistency_version` INT(10) UNSIGNED NOT NULL
      ) ENGINE=MyISAM;
      INSERT INTO `consistency_version` VALUES(1);
      

      然后像这样得到下一个数字:

      UPDATE consistency_version SET consistency_version = LAST_INSERT_ID(consistency_version +1);
      SET NEW.VERSION = LAST_INSERT_ID();
      

      这使用 LAST_INSERT_ID 作为保存下一个数字的临时位置。您可以在the manual 获得更多信息。

      序列表是MyISAM也很重要,避免在事务过程中长时间锁定。

      【讨论】:

      • 感谢您的回复,但我需要为每行而不是全局维护一个版本。我正在查看手册,我相信 OLD.VERSION 有效,而不是使用变量。
      【解决方案3】:

      如果我正确理解您的要求,以下将解决您的问题

      CREATE TRIGGER `TgrNAME` BEFORE UPDATE ON `PERSON` 
          FOR EACH ROW BEGIN
          set new.consistency_version = new.consistency_version +1 ;
       END
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-22
        • 1970-01-01
        • 2017-07-21
        • 1970-01-01
        • 2010-09-05
        相关资源
        最近更新 更多