首页 > 解决方案 > 循环遍历所有表并重命名列

问题描述

一个客户给了我一个旧数据库old_data,其中包含一堆表,我将在新系统中逐步激活这些表。不幸的是,有几个表包含一个名称的列,hash它不能很好地与我用来处理这个项目的 Ruby on Rails 一起浮动。

有没有办法在 MySQL 控制台中告诉 MySQL(版本 8.0.12)循环遍历给定数据库中的所有表并将列重命名为该列hash是否old_hash存在?

标签: mysqlsql

解决方案


幸运的是 MySQL 8 附带了一种ALTER TABLE RENAME COLUMN a TO b语法,因此您可以编写一个相当简单的存储过程来执行此操作。

DELIMITER //

CREATE PROCEDURE rename_columns(IN name_of_database CHAR(64),
                                IN old_name_of_column CHAR(64),
                                IN new_name_of_column CHAR(64))
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE name_of_table CHAR(64);
    DECLARE table_cursor CURSOR FOR
        SELECT TABLE_NAME FROM information_schema.COLUMNS
        WHERE TABLE_SCHEMA = name_of_database AND COLUMN_NAME = old_name_of_column;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    OPEN table_cursor;
    table_loop: LOOP
        FETCH table_cursor INTO name_of_table;
        IF done THEN LEAVE table_loop; END IF;
        SET @alter_sql = CONCAT(
            'ALTER TABLE ', name_of_database, '.', name_of_table,
            ' RENAME COLUMN ', old_name_of_column, ' TO ', new_name_of_column);
        PREPARE alter_statement FROM @alter_sql;
        EXECUTE alter_statement;
        DEALLOCATE PREPARE alter_statement;
    END LOOP;
    CLOSE table_cursor;
END//

DELIMITER ;

CALL rename_columns('old_data', 'hash', 'old_hash');

它在 5.7 和更早版本中更加复杂,因为您需要生成一个ALTER TABLE CHANGE a b ...包含完整列定义的语句。


推荐阅读