2012-10-22 78 views
3

觸發如下:爲什麼這個觸發器會讓我的一些插入操作掛起?

DELIMITER // 
CREATE TRIGGER `Conturi_BI` BEFORE INSERT ON `Conturi` FOR EACH ROW BEGIN 
SET NEW.CUI_cod = digits(NEW.CUI); 
END// 
DELIMITER ; 

我只是應用數字功能,用戶輸入速度匹配和重複搜索,但自從我實現它的一些我插入的只是掛。我做了一個類似的更新,它沒有同樣的問題。

數字函數是由我和觸發器創建的,大部分時間插入工作正常。

的數字功能,如要求:

BEGIN 
    DECLARE i, len SMALLINT DEFAULT 1; 
    DECLARE ret CHAR(32) DEFAULT ''; 
    DECLARE c CHAR(1); 
    SET len = CHAR_LENGTH(str); 
    REPEAT 
    BEGIN 
     SET c = MID(str, i, 1); 
     IF c BETWEEN '0' AND '9' THEN 
     SET ret=CONCAT(ret,c); 
     END IF; 
     SET i = i + 1; 
     END; 
    UNTIL i > len END REPEAT; 
    RETURN ret; 
END 
+0

你確定MySQL有'數字'功能嗎?我在Doc中找不到它。它不適用於[SQLFiddle](http://sqlfiddle.com/#!2/d41d8/2950),但我發現它[DB2](http://publib.boulder.ibm.com/infocenter/dzichelp /v2r2/index.jsp?topic=%2Fcom.ibm.db2.doc.sqlref%2Ffdigits.htm) –

+0

數字函數是由我添加的,觸發器也在大多數時間工作。 – Bogdan

+0

然後請顯示'數字'功能的代碼。問題可能在那裏。 –

回答

2

如果您將null傳遞給它,您的digit功能不起作用。它將永遠循環。與

select digits(null) 

試試吧所以每次NEW.CUI爲null,則它會讓你插入掛起。你可以在你的函數的開頭添加一個null檢查:

if str is null 
then 
    return ''; 
end if; 
1

我最好的猜測是,這是從「一些」說法來看,你得到一個問題lock contention

如果我理解你的觸發器正確,在寫入表A之前(實際上是)寫入表A時,觸發你的過程,這又會改變同一表中的每條記錄寫入的目的是專門鎖定單個事務中的每一行。

在另一個事務中執行此操作很可能會導致出現deadlock的情況,您的觸發器將等待升級鎖,其他事務將等待您的完成(如果您願意,則會死鎖)。

這一努力的成功至少取決於數據庫驅動程序的實現。鎖定一行,然後將其再次鎖定在觸發事務中大多數數據庫驅動程序假定可以擴大事務,但是,某些數據庫無法看到事務來自同一個連接並分別處理它們。

+0

不應該觸發器只鎖定新添加的行而不是整個表? – Bogdan

相關問題