【问题标题】:Transfer data from MySQL table to a different table将数据从 MySQL 表传输到不同的表
【发布时间】:2015-10-27 10:41:10
【问题描述】:

我有一个数据库,我们在我的计算机上简单地称它为“db”,其中有几个表,这些表中有多个列和这些表中的数据。 我有一个软件使用这个数据库来存储配置元素和其他一些东西。

现在,我发布了我的软件的新版本,仅对数据库进行了轻微修改,即某些列可能已添加到表中,或已删除(但没有重命名列)。

我必须保留所有数据,因此我想将其转移到我的数据库的新“版本”中。

我的想法:

  • 将“db”重命名为“db_old”。
  • 将新数据库安装为“db_new”,并在新列中使用默认值
  • 对于每个表,获取 'db_old' 中存在于 'db_new' 中的所有列的列表
  • 使用 INSERT INTO ... SELECT 将旧内容放回“db_new”。
  • 删除旧数据库并使用我的新数据库。

你认为它可以工作吗?你有什么简单的解决办法吗?

另外,我绝对不是 SQL 专家...我试过这个(没有查看该列是否已被删除):

SELECT 
    GROUP_CONCAT(COLUMN_NAME
        SEPARATOR ',')
INTO @colList FROM
    INFORMATION_SCHEMA.COLUMNS
WHERE
    TABLE_SCHEMA = 'db_old'
        AND TABLE_NAME = 'configuration';
INSERT 
INTO db_new.configuration (SELECT @colList)
SELECT @colList FROM
    db_old.configuration;

但是用有效列表替换第二个@colList 失败了......你也可以在这个问题上帮助我吗?

谢谢大家,祝你有美好的一天!

【问题讨论】:

  • 旧表中的列是否与新表中的列匹配?
  • 新表可能有新列,部分列可能已被删除。但是共同的列具有相同的名称。但是,如果这太复杂了,我们就说新表可能只有新列,而没有删除任何列。
  • 您应该能够将其保留为简单的insert into 语句。我最近不得不做同样的事情。 INSERT INTO database2.table (column_name(s)) SELECT (column_name(s)) FROM database1.table 将数据插入新数据库并将新列保留为空白/空
  • 非常感谢。我设法做到了只添加列的情况。我的代码是:SELECT GROUP_CONCAT(COLUMN_NAME SEPARATOR ', ') INTO @var1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'db1' AND TABLE_NAME = 'Table1'; SELECT @var1; SET @execut = CONCAT("INSERT INTO db2.Table2(", @var1, ") SELECT ", @var1, " FROM db1.Table1"); PREPARE stmt FROM @execut; EXECUTE stmt; 诀窍就是使用语句...
  • 好的,谢谢! :) 现在我只需要编写一个小例程来用两个表中都存在的列名填充变量,第二种情况将完成。我想我可以自己解决这个问题,再次感谢您! :)

标签: mysql sql migrate


【解决方案1】:

您应该首先转储您的 DB 数据库并创建一个 .sql 文件。根据您的数据库数据,此文件甚至可以以 GB 为单位。此 SQL 文件将包含您的所有表以及这些表中的所有数据。我会建议你打开并查看文件。 然后您应该使用这个新创建的文件并将所有数据导入新数据库。它会将所有这些表和数据放入这个新数据库中。

这里是如何做到这一点。首先创建SQL文件:

mysqldump -h [SeverIpAddress] -u [UserName] -p[password] YourDbname > db_backup.sql

在远程服务器的情况下使用 -h [SeverIpAddress]。万一它在您自己的系统中恢复,您不需要使用它。

然后你应该创建你的新数据库,比如说 DB_new。创建后,使用 use 命令切换到它。

use DB_new

完成后,现在导入我们在使用 source 命令之前创建的 .SQl 文件。

source YourSQLFilePath

在你的情况下,source db_backup.sql

【讨论】:

  • 这不是必需的,因为您可以直接从一个数据库传输到另一个数据库。
  • 谢谢,但它不能工作。转储将提取我的 old_db 架构(即列)以及数据。我需要的是在具有更多(或更少)列的表中插入旧数据。
【解决方案2】:

好的。如果有人遇到同样的问题,这里是解决方案。

首先,承认您有一个名为“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`;

瞧!只是不要忘记放回你丢弃的外键:)


当然可以以更好的方式完成,但我让它正常工作。

谢谢大家!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    • 1970-01-01
    • 2019-07-07
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 2021-12-27
    相关资源
    最近更新 更多