我需要將舊數據庫遷移到新數據庫。不幸的是,編寫舊數據庫的人使用逗號分隔外鍵的字段創建了n,n關係。MySQL CSV行爲多行
我想編寫一個mysql查詢(也許使用insert into ... select)來拆分這些逗號分隔的外鍵,以便我可以構建一個表,其中每行都是一個外鍵。
這可能嗎?
我需要將舊數據庫遷移到新數據庫。不幸的是,編寫舊數據庫的人使用逗號分隔外鍵的字段創建了n,n關係。MySQL CSV行爲多行
我想編寫一個mysql查詢(也許使用insert into ... select)來拆分這些逗號分隔的外鍵,以便我可以構建一個表,其中每行都是一個外鍵。
這可能嗎?
在純SQL中執行此操作並不簡單。使用您選擇的編程語言輪流檢索每條記錄並根據逗號分隔字段插入多對多連接表記錄將是最容易的。以下僞代碼提示您可能使用的方法:
for each (id, csv_foreign_keys) in source_rows do
foreign_keys = split ',', csv_foreign_keys
for each fk in foreign_keys do
insert (id, fk) into many-to-many link table
一旦完成此操作,可以刪除包含逗號分隔外鍵的現有列。
我的解決方案
DELIMITER $$
DROP FUNCTION IF EXISTS SPLITCVS $$
DROP PROCEDURE IF EXISTS MIGRATE $$
CREATE FUNCTION SPLITCVS (
x VARCHAR(255),
delim VARCHAR(12),
pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
delim, '') $$
CREATE PROCEDURE MIGRATE()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE id INT(11);
DECLARE csv BLOB;
DECLARE cur CURSOR FOR SELECT uid,foreigns FROM old;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur;
read_loop: LOOP
FETCH cur INTO id, csv;
IF done THEN
LEAVE read_loop;
END IF;
IF LENGTH(csv) <> 0 THEN
SET @i = 0;
SET @seps = LENGTH(csv) - LENGTH(REPLACE(csv, ',', ''));
IF RIGHT(csv,1) <> ',' THEN
SET @seps = @seps + 1;
END IF;
WHILE @i < @seps DO
SET @i = @i + 1;
INSERT INTO db.newtable(uid_local,uid_foreign)
VALUES (id,SPLITCVS(csv,',',@i));
END WHILE;
END IF;
END LOOP;
CLOSE cur;
END $$
CALL MIGRATE() $$
DROP FUNCTION SPLITCVS $$
DROP PROCEDURE MIGRATE $$
謝謝,它的工作原理,這是我的解決辦法 – 2011-02-18 14:53:49