mysql存储过程改变列类型

时间:2016-10-12 17:11:11

标签: mysql stored-procedures

在我的MySQL设置中,我有大约十几个包含数百个表的数据库,其中所有id字段都使用varchar(20)类型定义。每个数据库有几千个这样的字段。这些字段需要更改为varchar(36)。

为了实现这一点,我创建了一个存储过程:

  1. 获取所有适当的模式;
  2. 获取架构的表格;
  3. 遍历所有列,当列类型=' varchar(20)将列更改为varchar(36)。
  4. 该程序的内容如下。但是没有改变列类型,我什么都没得到。意思是有问题。但它是什么?

    你能救我吗?

    DELIMITER $$
    
    DROP PROCEDURE IF EXISTS `get_database`$$
    DROP PROCEDURE IF EXISTS `get_table`$$
    DROP PROCEDURE IF EXISTS `get_column`$$
    DROP PROCEDURE IF EXISTS `alter_column`$$
    
    CREATE PROCEDURE get_database()
    BEGIN
        DECLARE db_rows INT;
        DECLARE dbI INT DEFAULT 1;
        DECLARE db_name VARCHAR(255);
        DECLARE db_names CURSOR FOR SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME LIKE '%ofb%';
    
    SET @enabled = TRUE;
    select FOUND_ROWS() into db_rows;
    open db_names;
    db_loop: LOOP
        if dbI > db_rows THEN
            CLOSE db_names;
            LEAVE db_loop;
        end if;
        FETCH db_names INTO db_name;
        -- database found
        if db_name then
            call get_table(db_name);
        end if;
    
        SET @dbI = @dbI + 1;
    END LOOP db_loop;
    END $$
    
    CREATE PROCEDURE get_table(db_name VARCHAR(255))
    BEGIN
    DECLARE tn_rows INT;
    DECLARE tnI INT DEFAULT 1;
    DECLARE table_name VARCHAR(255);
    DECLARE table_names CURSOR FOR SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = db_name;
    SET @enabled = TRUE;
    SET tnI = 1;
    SET @enabled = TRUE;
    select FOUND_ROWS() into tn_rows;
    open table_names;
    table_loop: LOOP
        if tnI > tn_rows THEN
            CLOSE table_names;
            LEAVE table_loop;
        end if;
        FETCH table_names INTO table_name;
        -- table_name found
        if table_name then
            call get_column(db_name, table_name);
        end if;
        SET tnI = tnI + 1;
    END LOOP table_loop;
    END $$
    
    CREATE PROCEDURE get_column(db_name VARCHAR(255), table_name VARCHAR(255))
    BEGIN
    DECLARE cn_rows INT;
    DECLARE cnI INT DEFAULT 1;
    DECLARE column_name VARCHAR(255);
    DECLARE column_names 
        CURSOR FOR SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = db_name and TABLE_SCHEMA = table_name;
    SET @enabled = TRUE;
    SET cnI = 1;
    select FOUND_ROWS() into cn_rows;
    open column_names;
    column_loop: LOOP
        if cnI > nn_rows THEN
            CLOSE column_names;
            LEAVE column_loop;
        end if;
        FETCH column_names INTO column_name;
        -- column_name found
        if column_name then
            call alter_column(db_name, table_name, column_name);
        end if;
        SET cnI = cnI + 1;
    END LOOP column_loop;
    END $$
    
    CREATE PROCEDURE alter_column(db_name VARCHAR(255), table_name VARCHAR(255), column_name VARCHAR(255))
    BEGIN
    
    DECLARE dtype VARCHAR(255);
    declare data_type 
        CURSOR FOR SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS 
        WHERE TABLE_SCHEMA = table_name and TABLE_NAME = table_name AND COLUMN_NAME = column_name;
        open data_type;
        fetch data_type into dType;
        if dType = 'varchar(20)' then
            SET @ddl = CONCAT('alter table ', db_name, '.',table_name, ' modify column (', column_name, ' VARCHAR(36))');
            PREPARE STMT FROM @ddl;
            EXECUTE STMT;
        end if;
    END $$
    
    
    DELIMITER ;
    

    感谢您的帮助。

    祝你好运

1 个答案:

答案 0 :(得分:0)

我需要这些程序,并看到我所做的一些更改,这些更改有效:

创建程序 get_database() 开始 声明_table_name VARCHAR(255); DECLARE 完成 INTEGER DEFAULT 0;

DECLARE table_names CURSOR FOR 
    SELECT table_name 
        FROM INFORMATION_SCHEMA.TABLES WHERE 
        TABLE_SCHEMA like '%ofb%';

DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;

OPEN table_names;

table_loop: LOOP
    FETCH table_names INTO _table_name;
   
    IF finished = 1 THEN
        CLOSE table_names;
        LEAVE table_loop;
    END IF;
   
    CALL get_column('%ofb%', _table_name);

END LOOP table_loop;    

结束

CREATE PROCEDURE get_column(db_name VARCHAR(255), table_name VARCHAR(255)) 开始 声明_column_name VARCHAR(255); DECLARE 完成 INTEGER DEFAULT 0;

DECLARE column_names CURSOR FOR 
    SELECT column_name FROM 
        INFORMATION_SCHEMA.COLUMNS 
        WHERE table_schema LIKE db_name AND
        TABLE_NAME = _table_name AND
        DATA_TYPE = "varchar" AND
        CHARACTER_MAXIMUM_LENGTH = 20

DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;   

OPEN column_names;

column_loop: LOOP
    FETCH column_names INTO _column_name;

    IF finished = 1 THEN
        CLOSE column_names;
        LEAVE column_loop;
    END IF;

    SET @ddl = CONCAT('ALTER TABLE ', db_name, '.',_table_name, ' MODIFY COLUMN ', _column_name, ' VARCHAR(36) NULL');
    PREPARE STMT FROM @ddl;
    EXECUTE STMT;
    
END LOOP column_loop;

结束