2016-03-20 84 views
0

我有一个工作正常的触发器。触发器(AFTER/BEFORE)在Mysql

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; 
$$ 

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

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

UPDATE:

我跟着这个张贴在stackoverflow

+0

,想到的唯一的事情是,你从'null'改为第4列到''type'' - 也许第4列是不是'varchar'列? – radoh

+0

你忘了在'create trigger'命令中加入'DELIMITER $$'。在这个命令之后也不要忘记追加'DELIMITER;'。 – krokodilko

+0

@kordirko:你能解释一下吗? – DOE

回答

0

@kordirko: Can you please explain a little bit?

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

If you use the mysql client program to define a stored program containing semicolon characters, a problem arises. By default, mysql itself recognizes the semicolon as a statement delimiter, so you must redefine the delimiter temporarily to cause mysql to pass the entire stored program definition to the server.

To redefine the mysql delimiter, use the delimiter command. The following example shows how to do this for the dorepeat() procedure just shown. The delimiter is changed to // to enable the entire definition to be passed to the server as a single statement, and then restored to ; before invoking the procedure. This enables the ; delimiter used in the procedure body to be passed through to the server rather than being interpreted by mysql itself.


简单的例子 - 我使用MySQL工作台,并复制并粘贴您的触发器。首先是一些假表:

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 

结果=成功

+0

哦,是的,我发现像...分隔符// – DOE