我有一個存儲過程,它應該使用遊標處理表中的行。該程序大部分時間都在使用,但有時候它並沒有完全執行。我知道這一點,因爲我有一個簡單的調試工具,嵌入到代碼中,它將特定的行和變量記錄到專用的調試表中。最有趣的是,從PHP運行時總是會出現問題。如果我使用mysql客戶端,我從來沒有遇到這個問題。用遊標存儲過程以奇怪的方式執行
該過程(在一定程度上縮短的方式這裏介紹)如下:
CREATE PROCEDURE findnextedge(IN lastid BIGINT)
findnext_context:BEGIN
DECLARE stop BOOLEAN DEFAULT FALSE;
DECLARE count INT DEFAULT 0;
DECLARE cur_fid BIGINT DEFAULT 0;
DECLARE cur_pid1 BIGINT DEFAULT 0;
DECLARE cur_pid2 BIGINT DEFAULT 0;
DECLARE cur CURSOR FOR SELECT fid, pid1, pid2 FROM edges WHERE pid1 = lastid;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET stop = TRUE;
CALL debuglog(0, 'findnextedge', 'lastid', lastid, NULL, NULL, NULL, NULL);
SELECT SQL_CALC_FOUND_ROWS fid FROM edges WHERE pid1 = lastid;
SET count = FOUND_ROWS();
CALL debuglog(1, 'findnextedge', 'count', count, NULL, NULL, NULL, NULL);
IF count = 0 THEN
DELETE FROM paths WHERE pid1 = lastid AND pid2 = 0;
SELECT COUNT(*) INTO count FROM paths WHERE pid2 = 0;
CALL debuglog(2, 'findnextedge', 'count', count, NULL, NULL, NULL, NULL);
IF count = 0 THEN
SET @count = 1;
END IF;
LEAVE findnext_context;
END IF;
DELETE FROM paths WHERE pid1 = lastid AND pid2 = 0 ORDER BY pid1 LIMIT 1;
OPEN cur;
CALL debuglog(6, 'findnextedge', 'open', TRUE, NULL, NULL, NULL, NULL);
REPEAT
FETCH cur INTO cur_fid, cur_pid1, cur_pid2;
CALL debuglog(7, 'findnextedge', 'stop', stop, NULL, NULL, NULL, NULL);
IF stop = FALSE THEN
CALL debuglog(3, 'findnextedge', 'cur_fid', cur_fid, 'cur_pid1', cur_pid1, 'cur_pid2', cur_pid2);
// DO MAIN JOB
// ...
CALL debuglog(5, 'findnextedge', NULL, NULL, NULL, NULL, NULL, NULL);
END IF;
CALL debuglog(8, 'findnextedge', 'stop', stop, NULL, NULL, NULL, NULL);
UNTIL stop = TRUE
END REPEAT;
CLOSE cur;
END;
如果發生所產生的整個輸出該問題:
point context name1 value1 name2 value2 name3 value3 counter time
0 findnext lastid 0 NULL NULL NULL NULL 0 2012-11-27 18:29:56
1 findnext count 1 NULL NULL NULL NULL 1 2012-11-27 18:29:56
6 findnext open 1 NULL NULL NULL NULL 2 2012-11-27 18:29:56
7 findnext stop 0 NULL NULL NULL NULL 3 2012-11-27 18:29:56
根據日誌,在點7 ,剛剛取出光標stop
值爲假,但執行沒有達到第3點和第8點。
它看起來像一些內部錯誤occ但是我不確定我該如何去捕捉它。奇怪的是,這種情況發生在相同的數據上,不時發生,否則就會起作用。
P.S. MySQL版本5.0.51b,PHP 5.2.6。
P.S.S.我設法找到一個相關的問題 - Calling a Stored Procedure Within a Cursor Loop, Without Tripping the Continue Handler。正如我的程序的名稱所暗示的那樣,它從外部過程的循環內部被調用(順便說一下,它有一個循環遍歷「paths」表,另一個繼續處理程序),所以它類似於這種情況,可能是某種程度上重要。我已經嘗試了鏈接問題的解決方案,但它也沒有幫助。
找到了解決辦法,答案發布在以下。
感謝您的想法,但唉,它並沒有幫助。我發現了一個可能與之相關的bug:http://bugs.mysql.com/bug.php?id=12168(標記爲固定並在其他條件下顯示)。我打算找到解決方法。 – Stan