【问题标题】:Whats wrong with this mysql trigger definition?这个mysql触发器定义有什么问题?
【发布时间】:2020-01-22 17:41:11
【问题描述】:

只是不明白为什么会抛出这个错误:

ERROR 1064 (42000):您的 SQL 语法有错误;查看与您的 MariaDB 服务器版本相对应的手册,了解在第 1 行的“END”附近使用的正确语法

触发器定义如下:

CREATE TRIGGER `aaa` 
BEFORE INSERT ON `aaa_table`  
FOR EACH ROW
BEGIN
    IF (`NEW.field1` LIKE 'ABC-%')  
    AND 
        (SELECT COUNT(1) FROM `aaa_table` 
        WHERE `aaa_table.field2` = `NEW.field2` 
        AND `aaa_table.field3` = `NEW.field3`) > 0 
   THEN 
      SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'Verify Insert Failed - record Exists!'  
   END IF; 

   IF (`NEW.field1` NOT LIKE 'ABC-%')  
    AND 
        (SELECT COUNT(1) FROM `aaa_table` 
        WHERE `aaa_table.field2` = `NEW.field2` 
        AND `aaa_table.field4` = `NEW.field4`) > 0 
   THEN 
      SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'Verify Insert Failed - record Exists!'  
   END IF;
END

有人可以帮忙吗?

我也很高兴听到任何改进这种语法的想法。我正在尝试验证基于 field1 值的记录的唯一性 - 它的 LIKE 'ABC-%' 那么不应有超过一行具有相同的 field2 和 field3,否则不应该有多于一行具有相同的字段 2 和字段 4。 试图通过虚拟列来实现,但无法在这样的列上定义唯一键。

更新:

我尝试了@Baram 的建议:

CREATE TRIGGER `aaa` 
BEFORE INSERT ON `aaa_table`  
FOR EACH ROW
BEGIN
    IF (NEW.`field1` LIKE 'ABC-%')  
    AND 
        (SELECT COUNT(1) FROM `aaa_table` 
        WHERE `aaa_table`.`field2` = NEW.`field2` 
        AND `aaa_table`.`field3` = NEW.`field3`) > 0 
   THEN 
      SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'Verify Insert Failed - record Exists!';  
   END IF; 

   IF (NEW.`field1` NOT LIKE 'ABC-%')  
    AND 
        (SELECT COUNT(1) FROM `aaa_table` 
        WHERE `aaa_table`.`field2` = NEW.`field2` 
        AND `aaa_table`.`field4` = NEW.`field4`) > 0 
   THEN 
      SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'Verify Insert Failed - record Exists!';
   END IF;
END

但不断出现同样的错误。有什么想法吗?

谢谢!

更新 2

找到了问题,希望对遇到同样问题的人有所帮助:

我必须添加分隔符定义,这样查询就不会在分号上分成几个。

【问题讨论】:

  • 你不应该在 NEW.field1 周围有反引号,它们应该在 field1 周围。
  • 语法错误是因为在END IF之前的行尾需要;

标签: mysql


【解决方案1】:

语法错误是因为您忘记了END IF之前语句末尾的;

另外,NEW. 不应该在反引号内,它可以防止 NEW 被作为特殊关键字处理。同样,`aaa_table.fieldX` 应该是`aaa_table`.`fieldX`,这样. 将被视为分隔符而不是列名的一部分(尽管在这些查询中没有真正需要指定表名,因为它们只是从一张表中选择)。

CREATE TRIGGER `aaa` 
BEFORE INSERT ON `aaa_table`  
FOR EACH ROW
BEGIN
    IF (NEW.`field1` LIKE 'ABC-%')  
    AND 
        (SELECT COUNT(1) FROM `aaa_table` 
        WHERE `aaa_table`.`field2` = NEW.`field2` 
        AND `aaa_table`.`field3` = NEW.`field3`) > 0 
   THEN 
      SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'Verify Insert Failed - record Exists!';  
   END IF; 

   IF (NEW.`field1` NOT LIKE 'ABC-%')  
    AND 
        (SELECT COUNT(1) FROM `aaa_table` 
        WHERE `aaa_table`.`field2` = NEW.`field2` 
        AND `aaa_table`.`field4` = NEW.`field4`) > 0 
   THEN 
      SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'Verify Insert Failed - record Exists!';
   END IF;
END

您可以使用EXISTS 查询,而不是检查COUNT(1)。您可以将这两种变体结合起来。

IF IF(NEW.field1 LIKE 'ABC-%',
        EXISTS (
            SELECT 1 FROM aaa_table
            WHERE field2 = NEW.field2
            AND field3 = NEW.field3),
        EXISTS (
            SELECT 1 FROM aaa_table
            WHERE field2 = NEW.field2
            AND field4 = NEW.field4)
        )
THEN
    SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'Verify Insert Failed - record Exists!';  
END IF;

【讨论】:

  • 坦克,我尝试添加';'它抛出: ERROR 1064 (42000): You have an error in your SQL syntax;检查与您的 MariaDB 服务器版本相对应的手册,了解在第 12 行的 '' 附近使用的正确语法
  • 也尝试了简短的 if 想法,结果我得到: SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = '验证插入失败 - 记录存在!'查询中的错误 (1064):第 19 行 END IF 附近的语法错误 查询中的错误 (1064):第 1 行的 'END IF' 附近的语法错误 END 查询中的错误 (1064):第 1 行的 'END' 附近的语法错误1 我该怎么办?感觉缺少一些基本的东西
  • 在定义触发器之前是否有DELIMITER 语句,所以可以在里面使用;
  • 这实际上是问题所在,请参阅我的问题中的更新 2。谢谢!
猜你喜欢
  • 2013-12-06
  • 2011-02-11
  • 2012-04-26
  • 2022-01-21
  • 2011-08-16
  • 1970-01-01
  • 2017-12-24
  • 2014-11-29
相关资源
最近更新 更多