简体   繁体   English

将数据从MySQL表传输到其他表

[英]Transfer data from MySQL table to a different table

I have a database, let's simply call it 'db', on my computer, with a few tables that have multiple columns and data inside those tables. 我有一个数据库,在我的计算机上,我们简单地称它为“ db”,其中有一些表,这些表中有多个列和数据。 I have a software using this database to store configuration elements and some other stuff. 我有一个使用该数据库存储配置元素和其他内容的软件。

Now, I am releasing a new version of my software, with only slight modifications in the database, ie some columns may have been added to tables, or removed (but no column renamed). 现在,我发布了我的软件的新版本,仅对数据库进行了少量修改,即某些列可能已添加到表中或已删除(但未重命名列)。

I must keep all data, so I would like to transfer it to the new "version" of my database. 我必须保留所有数据,因此我想将其传输到数据库的新“版本”中。

What I thought of : 我的想法:

  • Rename 'db' into 'db_old'. 将“ db”重命名为“ db_old”。
  • Install the new database as 'db_new', with the default values in the new columns 将新数据库安装为“ db_new”,并在新列中使用默认值
  • For each table, get a list of all the columns from 'db_old' that are present in 'db_new' 对于每个表,获取“ db_new”中存在的“ db_old”中所有列的列表
  • Use a INSERT INTO ... SELECT to put that old stuff back into 'db_new'. 使用INSERT INTO ... SELECT将旧内容放回db_new。
  • drop the old db and use my new db. 删除旧数据库并使用我的新数据库。

Do you think it can work ? 您认为它可以工作吗? Do you have any easy solution ? 您有任何简单的解决方案吗?

Also, I'm absolutely not an SQL expert... And I tried this (without looking if the column has been removed or not yet) : 另外,我绝对不是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;

But it fails on replacing the second @colList by the effective list... Can you also help me on this issue ? 但是它无法将第二个@colList替换为有效列表...您还能在这个问题上帮助我吗?

Thank you everyone and have a nice day ! 谢谢大家,祝你有美好的一天!

You should first take a dump of your DB Database and create a .sql file. 首先,您应该转储数据库数据库并创建一个.sql文件。 Depending upon on your DB Data, this file can even go in GBs. 根据您的数据库数据,该文件甚至可以以GB为单位。 This SQL File will contain all your tables and all the data inside those tables. 该SQL文件将包含您的所有表以及这些表中的所有数据。 I will suggest you open and see the file. 我建议您打开并查看文件。 Then you should use this new created file and use it to import all the data into new DB. 然后,您应该使用这个新创建的文件,并将其用于将所有数据导入新数据库。 It will put all those tables, data into this new DB. 它将所有这些表,数据放入这个新的数据库中。

Here is how to do that. 这是这样做的方法。 First create SQL file: 首先创建SQL文件:

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

Use -h [SeverIpAddress] in case of Remote severs. 如果是远程服务器,请使用-h [SeverIpAddress]。 In case, it resdies in your own system, you don't need to use this. 万一它驻留在您自己的系统中,则无需使用它。

Then You should create your new DB, lets say DB_new. 然后,您应该创建新的数据库,假设为DB_new。 once created, switch to it using use command. 创建完成后,使用use命令切换到该位置。

use DB_new

Once done, now import your .SQl file that we have created before using source command. 完成后,现在导入您在使用source命令之前创建的.SQl文件。

source YourSQLFilePath

In your case, source db_backup.sql 在您的情况下, source db_backup.sql

OK. 好。 If anyone ever encounter the same problem, here is the solution. 如果有人遇到过同样的问题,这是解决方案。

First, admit you have a database called 'myDatabase', with a table called 'myTable' that you want to "upgrade", ie you want to modify the table structure by adding/removing columns but keep the data inside. 首先,承认您有一个名为“ myDatabase”的数据库,其中包含一个要“升级”的名为“ myTable”的表,即,您想通过添加/删除列来修改表结构,但将数据保留在其中。


First step is to drop foreign keys (if any) and to rename "myTable" : 第一步是删除外键(如果有)并重命名“ myTable”:

USE `myDatabase`;

ALTER TABLE `myTable` DROP FOREIGN KEY `my_fk_constraint`;
ALTER TABLE `myTable` RENAME TO `old_myTable`;

Second step is to import the new table structure, by using SOURCE for example. 第二步是例如通过使用SOURCE导入新的表结构。

SOURCE C:/new_table_structure.sql

Third step is optional, but you may need this if your table has a lot of columns : 第三步是可选的,但如果表中有很多列,则可能需要这样做:

USE `myDatabase`;    
SET GLOBAL group_concat_max_len = 4294967295;

Fourth step is to store the following routine : 第四步是存储以下例程:

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 ;

Final step is to call the procedure on tables, and to drop the temporary table: 最后一步是在表上调用该过程,并删除临时表:

CALL updateConf( 'myDatabase', 'old_myTable', 'myTable', 'primaryKeyName' );

DROP TABLE `old_myTable`;

And voila ! 瞧! Just don't forget to put back the foreign keys you dropped :) 只是不要忘记放回您放下的外键:)


It surely can be done in better ways, but i got this to work correctly. 当然可以用更好的方法来完成,但是我让它可以正常工作。

Thank you everyone ! 谢谢大家 !

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM