2014-10-20 30 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 $$