2014-10-20 29 views
-1

我想定义一个触发器来检查特定值的条目数,并且如果数字大于三,则不允许使用该特定行来输入新行。但是它会引发错误。 这里是我的代码:重复sql行上的触发器

delimiter $$ 

CREATE TRIGGER `timeslotattendantcheck` 
BEFORE INSERT ON `attendants` 
FOR EACH ROW 
BEGIN 
    DECLARE v_dup int; 
    SET v_dup = (SELECT COUNT(*) from attendants where attendant = NEW.attendant); 
    if v_dup > 3 then 
     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Too many attendants for one time slot. The insert is cancelled.'; 
    end if; 
end $$ 

delimiter ; 
+0

让我们不提它抛出的错误。 – 2014-10-20 19:59:15

+0

你在你的sql语法中有错误;请查看与您的mysql服务器版本对应的'signal sqlstate'45000'设置message_text ='太多的服务员一次性'在第5行的手册 – gnas 2014-10-20 20:01:17

+0

您使用的是什么版本的MySQL? – 2014-10-20 20:02:44

回答

0

SIGNAL没有在5.1支持。你需要升级到5.5以上,并且5.6已经考虑了相当长的一段时间,所以你可能会考虑升级到那个版本。

如果您正在使用innodb,那么如果表格变大,此表格将不会缩放。鉴于innodb计数的MVCC性质()不是像MyIASM中那样的快速原子查找。足够大的表格可能需要几分钟才能运行计数()。这意味着每个插入尝试都将受到限制。

+0

嗨,感谢您的回复。有关运行时间复杂性问题的解决方法吗? – gnas 2014-10-20 20:47:20

+0

好吧,如果服务员被编入索引,并且您将每个值的基数限制为仅为4,那么计数可能不会太可怕。 – atxdba 2014-10-20 21:07:33

+0

听起来不错,然后:-)另一件事是,我有另一个计数()函数在同一个触发器为一个不同的变量,这将是数到40而不是4,你认为运行时间将仍然正常? – gnas 2014-10-20 21:57:03

0

这招我与MySQL 5.1中使用的募集错误触发时,一些条件得到满足:

  1. 创建不插入视图,例如:

    CREATE OR REPLACE VIEW no_edit_view AS 
        SELECT 1 FROM dual 
    
  2. 如果您需要引发错误,然后尝试将值插入到此视图中:

    INSERT INTO no_edit_view VALUES (1); 
    

    you ge牛逼错误,如:“刀片的目标表no_edit_view不插入,进入

是,错误消息并不友好,但它的解决办法,如果你不能升级的MySQL服务器。


,您的触发,则:

CREATE TRIGGER `timeslotattendantcheck` 
BEFORE INSERT ON `attendants` 
FOR EACH ROW 
BEGIN 
    DECLARE v_dup int; 
    SET v_dup = (SELECT COUNT(*) from attendants where attendant = NEW.attendant); 
    if v_dup > 3 then 
     -- SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Too many attendants for one time slot. The insert is cancelled.'; 
     -- workaround: 
     INSERT INTO no_edit_view VALUES (1); 
    end if; 
end $$