MySQL 中的 BEFORE INSERT 触发器

Han*_*ans 4 mysql trigger mysql-5.5

我是 MySQL 的新手,我在创建BEFORE INSERT触发器时遇到了问题。

我收到一个unexpected END错误。

我有一个以verlof_aanvragen列命名的表datum(还有 6 列)。

我想要完成的只是日期介于now()+8和之间now()+365CURDATE() + INTERVAL 8 DAY AND CURDATE() + INTERVAL 365 DAY) 可以插入的行。日期超出该间隔的插入应该失败。

我使用的是 MySQL 5.5.24 版。

这是代码:

CREATE TRIGGER chk_dates  
BEFORE INSERT ON verlof_aanvragen  
FOR EACH ROW  
BEGIN  
  IF (NEW.datum < CURDATE() + INTERVAL 8 DAY OR NEW.datum > CURDATE() + INTERVAL 365 DAY) 
THEN  
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Any Message'

END IF  
END 
Run Code Online (Sandbox Code Playgroud)

Rol*_*DBA 5

我以前处理过这个问题。当涉及到触发器时,MySQL 的架构非常脆弱。

我之前写过关于如何在中途中断触发器的帖子。该解决方案相当令人讨厌,并且会在本月让纯 SQL 开发人员的品味不佳。

话虽如此,以下是我希望对您有所帮助的帖子:

由于您是新手,编写触发器代码需要将分隔符更改为分号以外的其他内容,然后再更改回来。

DELIMITER $$

CREATE TRIGGER chk_dates  
BEFORE INSERT ON verlof_aanvragen  
FOR EACH ROW  
BEGIN  
  IF (NEW.datum < CURDATE() + INTERVAL 8 DAY OR NEW.datum > CURDATE() + INTERVAL 365 DAY) 
THEN  
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Any Message';
END IF;
END $$

DELIMITER ;
Run Code Online (Sandbox Code Playgroud)

请回顾我的帖子,看看我是如何在我的代码中做到这一点的。

更新 2013-06-12 11:34 EDT

这是你的最后一条评论

我在 mysql server v 5.5.24 上使用上面的触发器,它工作正常。这是我的本地测试站点。现在我想在我的虚拟主机上使用它,他们有 mysql server v 5.1.56 ...而且它赢了;不工作!我错过了什么吗?

问题是 MySQL 版本。如果你回顾我的两个触发帖子,我使用黑市技术来打破中游触发。这对于旧版本的 MySQL 是必需的。请注意我Apr 25, 2011Trigger in MySQL 中所说的以防止插入

书中建议以这种方式抢占触发器的原因源于 MySQL 存储过程语言没有在语言中实现 SIGNAL(当然,SIGNAL 是 ANSI 标准)。

这本书的作者通过调用语法正确但在运行时失败的 SQL 语句来创建变通方法。本书的第 144-145 页(第 6 章:错误处理)给出了直接(示例 6-18)或通过信号仿真(示例 6-19 和 6-20)抢占存储过程的示例。

我直接引用了本书的第254-256页

dlckxmd

请注意以下事项:

因此,信号处理在 MySQL 5.1 中不起作用

您必须执行以下操作:

  • 重写 MySQL 5.1 中的触发器以打破中游
  • 你在 MySQL 5.5 数据库中编写的触发器应该保持现在的样子

这就是触发器在 MySQL 5.1 中不起作用的原因。

更新 2013-06-12 11:44 EDT

以下是您可以对 MySQL 5.1.56 数据库中的触发器执行的操作

DELIMITER $$

CREATE TRIGGER chk_dates  
BEFORE INSERT ON verlof_aanvragen  
FOR EACH ROW  
BEGIN  
  DECLARE dummy INT;
  IF (NEW.datum < CURDATE() + INTERVAL 8 DAY OR NEW.datum > CURDATE() + INTERVAL 365 DAY) 
THEN  
  SELECT 'Any Message' INTO dummy FROM mysql.user WHERE used = 'anything';
END IF;
END $$

DELIMITER ;
Run Code Online (Sandbox Code Playgroud)

由于mysql.user没有名为used的列,查询不会执行,从而破坏了触发器。