2016-02-11 72 views
2

目前,我們的應用程序的數據庫存儲了GMT-8中的所有DATETIME值,這通常非常糟糕。我們正在嘗試將應用程序和所有數據轉換爲使用UTC。動態地將數據庫中的所有DATETIME值轉換爲MySQL中的UTC

我試圖寫一個一次性的存儲過程,將查詢我的數據庫的模式,找到DATETIME型或TIMESTAMP的所有列,並自動與CONVERT_TZ()功能轉換值來更新列。

使用所有的到目前爲止,我已經找到了有關遊標,動態報表的編制,以及錯誤處理的信息,我想出了這一點:

DELIMITER $$ 

CREATE PROCEDURE `sp_convertDBtoUTC`() 
BEGIN 
    DECLARE `_rollback` BOOL DEFAULT 0; 
    DECLARE done INT DEFAULT 0; 
    DECLARE tname VARCHAR(64); 
    DECLARE cname VARCHAR(64); 

    DECLARE dt_columns CURSOR FOR 
     SELECT table_name, column_name 
     FROM information_schema.columns 
     WHERE table_schema = 'my_schema' 
      AND data_type IN ('datetime', 'timestamp') 
     ORDER BY table_name, column_name; 

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET `_rollback` = 1; 

    START TRANSACTION; 

    OPEN dt_columns; 

    table_loop: 
    LOOP 
     FETCH dt_columns INTO tname, cname; 

     IF done = 1 THEN 
      LEAVE table_loop; 
     END IF; 

     SET @stmt = CONCAT('UPDATE ',tname,' SET ',cname, ' = CONVERT_TZ(',cname, ', \'America/Los_Angeles\', \'UTC\')'); 
     PREPARE stmt FROM @stmt; 
     EXECUTE stmt; 

     DEALLOCATE PREPARE stmt; 
    END LOOP; 

    CLOSE dt_columns; 

    IF `_rollback` THEN 
     ROLLBACK; 
    ELSE 
     COMMIT; 
    END IF; 

END$$ 

這似乎沒有錯誤運行,但不會沒有。如果我在那裏添加一個SELECT @stmt語句,我會得到具有正確SQL的多個結果集,例如UPDATE tz_test SET dts = CONVERT_TZ(dts, 'America/Los_Angeles', 'UTC')。如果我手動運行這個語句,表格按預期更新。

但是,當運行存儲過程來更新整個數據庫時,表中的數據實際上並未更新,我不明白爲什麼。

我使用下面作爲測試:

CREATE TABLE tz_test (id INT auto_increment, dts DATETIME, PRIMARY KEY (id)); 
INSERT INTO tz_test (dts) VALUES (NOW()); 

SELECT * FROM tz_test; 
CALL sp_convertDBtoUTC(); 
SELECT * FROM tz_test; 

我本來期望第二結果設置爲包含修飾的日期時間值,但兩個結果集是相同的。爲什麼是這樣?

+0

您可以通過使用'rdebug'來查看發生了什麼,它是一個存儲在common_schema中的例程調試器:https://common-schema.googlecode.com/svn/trunk/common_schema/doc /html/rdebug.html –

回答

0

當試圖通過MySQL Workbench運行這些查詢時,由於安全模式(沒有大量更新/刪除而沒有對主鍵的引用),它們實際上正在失敗。

一旦我將其關閉並重新連接,整個過程完美無瑕。

相關問題