【问题标题】:Trigger (AFTER/BEFORE) In Mysql在 Mysql 中触发(之后/之前)
【发布时间】:2016-03-20 08:17:56
【问题描述】:

我有一个工作正常的触发器。

CREATE TRIGGER crm_listings__au 
AFTER UPDATE 
ON crm_listings FOR EACH ROW
    INSERT INTO crm_listings_versions 
        SELECT 
            'update', NULL, NOW(), NULL, d.*
        FROM 
            crm_listings AS d 
        WHERE 
            d.id = NEW.id;

现在我还想跟踪字段列名。我想我不能在上面的查询中做,所以我改为下面的触发器

CREATE TRIGGER crm_listings__au 
BEFORE UPDATE 
ON crm_listings 
FOR EACH ROW
BEGIN
    IF OLD.type != NEW.type
    THEN
        INSERT INTO crm_listings_versions  
            SELECT 
                'update', NULL, NOW(), 'type', d.* 
            FROM 
                crm_listings AS d 
            WHERE 
                d.id = NEW.id;
    END IF;

    IF OLD.price != NEW.price
    THEN
        INSERT INTO crm_listings_versions 
            SELECT  
                'update', NULL, NOW(), 'price', d.* 
            FROM 
                crm_listings AS d
            WHERE 
                d.id = NEW.id;
    END IF;
END;
$$

当我运行这段代码时,我得到了这个错误:

您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 10 行的 '' 附近使用正确的语法

更新:

我在stackoverflow关注了这篇文章

【问题讨论】:

  • 唯一想到的是您将第 4 列从 null 更改为 'type' - 也许第 4 列不是 varchar 列?
  • 您忘记在create trigger 命令前添加DELIMITER $$。另外不要忘记在此命令后附加DELIMITER ;
  • @kordirko:你能解释一下吗?
  • @radoh: 它的字符串,这里是代码我是怎么做的......在 dt_datetime 之后添加 action_field VARCHAR(8) NOT NULL DEFAULT 'id',
  • 嗯,好吧,我想那不是问题所在。不过我想知道 - 看到它被定义为NOT NULL,你以前的触发器怎么能工作,因为你插入了NULL...?

标签: mysql triggers insertafter


【解决方案1】:

@kordirko:你能解释一下吗?

请阅读文档:http://dev.mysql.com/doc/refman/5.7/en/stored-programs-defining.html

如果使用mysql客户端程序定义存储程序 包含分号字符,就会出现问题。 默认情况下,mysql 本身将分号识别为语句分隔符,因此您必须 临时重新定义分隔符,使mysql通过整个 将程序定义存储到服务器。

要重新定义 mysql 分隔符,请使用 delimiter 命令。这 以下示例显示了如何为 dorepeat() 过程执行此操作 刚刚显示。分隔符更改为 // 以启用整个 定义作为单个语句传递给服务器,然后 恢复到 ;在调用程序之前。这使 ; 过程主体中使用的分隔符传递给 服务器而不是由 mysql 本身解释。


简单示例 - 我正在使用 MySql Workbench 并复制并粘贴了您的触发器。首先是一些虚拟表:

create table crm_listings(
   id int,
   type int,
   price int
);

create table crm_listings_versions(
   ttype varchar(100),
   something varchar(100),
   d date,
   something1 varchar(100),
   id int,
   type int,
   price int
);

现在我运行你的代码没有DELIMITER

CREATE TRIGGER crm_listings__au BEFORE UPDATE ON crm_listings 

FOR EACH ROW

 BEGIN
    IF OLD.type != NEW.type
    THEN


        INSERT INTO crm_listings_versions SELECT 'update', NULL, NOW(), 'type', d.* FROM crm_listings AS d WHERE d.id = NEW.id;

    END IF;
    IF OLD.price != NEW.price
    THEN


        INSERT INTO crm_listings_versions SELECT 'update', NULL, NOW(), 'price', d.* FROM crm_listings AS d WHERE d.id = NEW.id;

    END IF;
END;
$$

Error Code: 1064. You have an error in your SQL syntax; check the manual 
that corresponds to your MySQL server version 
for the right syntax to use near '' at line 10  0.000 sec

结果 = 错误


然后相同,但使用 DELIMITER 命令:

DELIMITER $$
CREATE TRIGGER crm_listings__au BEFORE UPDATE ON crm_listings 

FOR EACH ROW

 BEGIN
    IF OLD.type != NEW.type
    THEN


        INSERT INTO crm_listings_versions SELECT 'update', NULL, NOW(), 'type', d.* FROM crm_listings AS d WHERE d.id = NEW.id;

    END IF;
    IF OLD.price != NEW.price
    THEN


        INSERT INTO crm_listings_versions SELECT 'update', NULL, NOW(), 'price', d.* FROM crm_listings AS d WHERE d.id = NEW.id;

    END IF;
END;
$$

DELIMITER ;

0 row(s) affected

结果 = 成功

【讨论】:

  • 哦,是的,我发现像 ... delimiter //
猜你喜欢
  • 1970-01-01
  • 2022-12-05
  • 1970-01-01
  • 1970-01-01
  • 2017-08-15
  • 2014-03-16
  • 1970-01-01
  • 2014-11-05
  • 1970-01-01
相关资源
最近更新 更多