確定。如果有人遇到同樣的問題,這裏是解決方案。首先,承認你有一個名爲'myDatabase'的數據庫,有一個名爲'myTable'的表,你想要「升級」,即你想通過添加/刪除列來修改表結構,但是保留數據在裏面。
第一步是刪除外鍵(如果有的話),並重新命名「myTable的」:
USE `myDatabase`;
ALTER TABLE `myTable` DROP FOREIGN KEY `my_fk_constraint`;
ALTER TABLE `myTable` RENAME TO `old_myTable`;
第二步是導入新的表結構,使用SOURCE例如。
SOURCE C:/new_table_structure.sql
第三步是可選的,但是你可能需要這個,如果你的表有很多列:
USE `myDatabase`;
SET GLOBAL group_concat_max_len = 4294967295;
第四步是存儲以下程序:
delimiter //
DROP PROCEDURE IF EXISTS updateConf//
CREATE PROCEDURE updateConf(IN dbName TEXT, IN old_table TEXT, IN new_table TEXT, IN primary_key_name TEXT)
BEGIN
-- get column count in old table
SELECT count(*)
INTO @colNb
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = dbName
AND TABLE_NAME = old_table;
-- get string with all column names from old_table
SELECT GROUP_CONCAT(COLUMN_NAME)
INTO @colNames1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = dbName
AND TABLE_NAME = old_table;
SET @colNames1 = CONCAT(@colNames1, ',');
-- get string with all column names from new_table
SELECT GROUP_CONCAT(COLUMN_NAME)
INTO @colNames2
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = dbName
AND TABLE_NAME = new_table;
-- variables initialization
SET @cpt = 1; -- column number counter
SET @pos = 1; -- position of column name first char
SET @vir = 1; -- next comma position
-- start of loop
label: LOOP
IF @cpt <= @colNb THEN
SET @vir = LOCATE(',',@colNames1,@pos); -- localize next comma
SET @colName = SUBSTRING(@colNames1, @pos, @vir - @pos); -- get column name
SET @pos = @vir + 1; -- update next column position
-- if column is in both tables
IF FIND_IN_SET(@colName, @colNames2) AND @colName != primary_key_name THEN
SET @execut = CONCAT("INSERT INTO ", new_table, " (", primary_key_name, ",", @colName, ") SELECT ", primary_key_name, ",", @colName, " FROM ", old_table, " ON DUPLICATE KEY UPDATE ", new_table, ".", @colName, " = ", old_table, ".", @colName);
PREPARE stmt FROM @execut;
EXECUTE stmt;
END IF;
SET @cpt = @cpt + 1; -- counter increment
-- when all columns parsed
ELSE
LEAVE label; -- end of loop
END IF;
END LOOP label;
END //
delimiter ;
最後一步是調用表的程序,並刪除臨時表:
CALL updateConf('myDatabase', 'old_myTable', 'myTable', 'primaryKeyName');
DROP TABLE `old_myTable`;
瞧!只是不要忘了放回你掉:)
就一定能更好的方式來完成的外鍵,但我得到這個才能正常工作。
謝謝大家!
請問您的舊錶中的列是否與新表中的列匹配? – Takarii
新表可能有新列,某些列可能已被刪除。但是通用的列名稱相同。但是,如果這太複雜了,我們只是說新表可能只有新列,並且沒有列被刪除。 – Yggdrazil
你應該能夠保持它作爲一個簡單的'insert into'語句。我最近不得不做同樣的事情。 'INSERT INTO database2.table(column_name(s))SELECT(column_name(s)) FROM database1.table'這會將數據插入到新數據庫中,並將新列保留爲空/空 – Takarii