目前,我們的應用程序的數據庫存儲了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;
我本來期望第二結果設置爲包含修飾的日期時間值,但兩個結果集是相同的。爲什麼是這樣?
您可以通過使用'rdebug'來查看發生了什麼,它是一個存儲在common_schema中的例程調試器:https://common-schema.googlecode.com/svn/trunk/common_schema/doc /html/rdebug.html –