2017-03-09 60 views
-1

我使用了一個存儲過程,它在第一次調用該過程後使用遊標循環並處理Mariadb 10.1數據庫上的出勤數據表,該數據庫中的所有表都丟失了執行INSERT INTO或UPDATE語句,除非目標表首先截斷,任何一個可以告訴我什麼地方出了錯,以及如何解決它 導致問題的過程:所有表都不能執行INSERT或UPDATE

DELIMITER $$ 
CREATE DEFINER=`root`@`localhost` PROCEDURE `settle_attendance`() 
    MODIFIES SQL DATA 
BEGIN 
DECLARE trans_done BOOLEAN DEFAULT FALSE; 
DECLARE punchid BIGINT(20); 
DECLARE timein DATETIME; 
DECLARE utctimein DATETIME; 
DECLARE timeout DATETIME; 
DECLARE utctimeout DATETIME; 
DECLARE inday DATE; 
DECLARE outday DATE; 
DECLARE todaysdate DATE; 

DECLARE attendcur CURSOR FOR 
    SELECT id, punch_in_utc_time, punch_in_user_time, 
       punch_out_utc_time, punch_out_user_time 
     FROM ohrm_attendance_record 
     ORDER BY id ASC; 
DECLARE CONTINUE HANDLER FOR NOT FOUND SET trans_done = TRUE; 

OPEN attendcur; 
edit_loop: LOOP 
SET todaysdate = CURRENT_DATE(); 
FETCH attendcur INTO punchid, utctimein, timein, utctimeout, timeout; 

IF trans_done THEN 
     CLOSE attendcur; 
     LEAVE edit_loop; 
END IF; 

SET inday = DATE(timein); 
SET outday = DATE(timeout); 
SET todaysdate = CURRENT_DATE(); 


IF (inday < todaysdate) OR (outday < todaysdate) THEN 
    CASE 
     WHEN (timein IS NULL OR timein = '') 
      OR (utctimein IS NULL OR utctimein = '') THEN 
      UPDATE ohrm_attendance_record 
       SET punch_in_utc_time = utctimeout, 
        punch_in_user_time = timeout, 
        state = 'PUNCHED OUT' 
       WHERE punchid = id; 
     ELSE BEGIN END; 
    END CASE; 

    CASE 
     WHEN (timeout IS NULL OR timeout = '') 
      OR (utctimeout IS NULL OR utctimeout = '') THEN 
      UPDATE ohrm_attendance_record 
       SET punch_out_utc_time = utctimein, 
        punch_out_user_time = timein, 
        state = 'PUNCHED OUT' 
       WHERE punchid = id; 
     ELSE BEGIN END; 
    END CASE; 
END IF; 

END LOOP edit_loop; 
END $$ 
DELIMITER ; 
+0

你是什麼意思「表丟失執行插入的能力」?如果你得到任何錯誤,逐字添加到你的問題。 – mustaccio

+0

當我手動執行查詢它的工作原理,但它不能在存儲過程中工作 –

回答

0

我選擇逃避你問的問題。相反,讓我們試着通過擺脫討厭的CURSOR來快速執行10次查詢。整個存儲過程可以在2 UPDATEs完成,沒有循環:

UPDATE ohrm_attendance_record 
    SET punch_in_utc_time = utctimeout, 
     punch_in_user_time = timeout, 
     state = 'PUNCHED OUT' 
    WHERE (timein < CURDATE() OR timeout < CURDATE()) 
     AND ((timein IS NULL  OR timein = '') 
      OR (utctimein IS NULL OR utctimein = '') 
      ); 

UPDATE ohrm_attendance_record 
    SET punch_out_utc_time = utctimein, 
     punch_out_user_time = timein, 
     state = 'PUNCHED OUT' 
    WHERE (timein < CURDATE() OR timeout < CURDATE()) 
     AND ((timeout IS NULL OR timeout = '') 
      OR (utctimeout IS NULL OR utctimeout = '') 
      ); 

我,不過,你可疑檢查對timeintimeout的。

如果您在NULL''中選擇了缺失的時間,那麼查詢會更容易閱讀。

如果僅存儲TIMESTAMP中的UTC值,則可以讓用戶的時區負責轉換爲當地時間 - 這將消除很多列並簡化UPDATEs

我會在這個問題做一個刺......難道SHOW CREATE PROCEDURE settle_attendance;,您可以發現CHARACTER SETCOLLATION是什麼,你認爲它應該是不一致的。

+0

謝謝你真的徹底弄清了過程。我只是在凌晨3點驚慌失措,在涉及遊標的多個程序上工作(我討厭它們,但我需要它們),結果問題變成了另一個調用這個程序的過程中表格錯位的名稱。 –

+0

在這個論壇中,包含'CURSOR'的大多數問題都可以在沒有這樣的情況下重寫。你的另一個例子。有時候最好是明天去睡覺並重新看看。 –

+0

我正在使用一個包含遊標的過程,它的不一致行爲現在讓我瘋狂了好幾天 –

相關問題