2011-02-18 45 views
3

我需要將舊數據庫遷移到新數據庫。不幸的是,編寫舊數據庫的人使用逗號分隔外鍵的字段創建了n,n關係。MySQL CSV行爲多行

我想編寫一個mysql查詢(也許使用insert into ... select)來拆分這些逗號分隔的外鍵,以便我可以構建一個表,其中每行都是一個外鍵。

這可能嗎?

回答

2

在純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 

一旦完成此操作,可以刪除包含逗號分隔外鍵的現有列。

+0

謝謝,它的工作原理,這是我的解決辦法 – 2011-02-18 14:53:49

0

我的解決方案

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 $$