2010-03-29 48 views
29

我有一個表包含一個url和一個字符串表示其參數。問題是我想要一個url和一個參數字符串作爲表的唯一約束 - 又沒有條目可以有相同的URL和參數字符串。參數字符串可以是任意長度(長度大於800bytes,這是MySql鍵的最大長度,所以我不能使用Unique(url,params),因爲它會引發錯誤...)。如何在MySql觸發器中取消INSERT操作?

我想過使用觸發器來做到這一點,但是如果觸發器發現插入件即將插入重複條目,我該如何拋出異常/產生錯誤?我想我希望MySqlException拋出像MySql一樣的重複主鍵等,所以我可以在我的C#代碼中捕獲它。

我在觸發器中有兩個部分我需要幫助: ...中止拋出異常到C#...我如何拋出異常等C#? ...允許插入... - 如何在沒有重複條目的情況下允許插入?

繼承人的觸發代碼:

CREATE TRIGGER urls_check_duplicates 
BEFORE INSERT ON urls 
FOR EACH ROW 

BEGIN 
DECLARE num_rows INTEGER; 

SELECT COUNT(*) 
INTO num_rows 
FROM urls 
WHERE url = NEW.url AND params = NEW.params; 

IF num_rows > 0 THEN 
    ... ABORT/throw exception to C# ... 
ELSE 
    ... Allow insert ... 
END 
+0

從MySQL 5.5,可能更早,可以使用的信號,[在這裏看到我的答案] [1] [1]:http://stackoverflow.com/questions/24/throw-error- in-mysql-trigger/7189396#7189396 – RuiDC 2011-08-25 11:20:16

回答

6

如果您的表定義是針對NOT NULL值的,則可以將NEW設置爲NULL,這實際上不會執行插入操作。您可能必須打開嚴格的sql模式才能正常工作。

67

我碰到過這個問題,雖然解決方案有效,但後來我發現我感覺像是一個更好的解決方案。當我回答這個問題時,我懷疑這不是一種選擇。

CREATE TRIGGER `TestTable_SomeTrigger` 
BEFORE UPDATE ON `test_table` 
FOR EACH ROW 
BEGIN 
    DECLARE msg VARCHAR(255); 
    IF (SomeTestToFail = "FAIL!") THEN 
     set msg = "DIE: You broke the rules... I will now Smite you, hold still..."; 
     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; 
    END IF; 

    -- Do any other code here you may want to occur if it's all OK or leave blank it will be 
    -- skipped if the above if is true 
END$$ 

這會返回一個很好的(或者邪惡的)錯誤信息,你可以捕獲它。 欲瞭解更多詳情請參閱:http://dev.mysql.com/doc/refman/5.5/en/signal.html

我希望這可以幫助別人!

+2

這真是太神奇了。爲我工作。 – rishad2m8 2015-05-31 14:54:20

+1

謝謝。我需要一個表格並強制執行非重疊範圍,這使我能夠做到這一點。 – Kickstart 2015-12-08 13:59:14

+1

這應該是被接受的答案... UP VOTE! – smashing 2017-03-10 12:37:10