简体   繁体   English

mysql 存储过程来改变列类型

[英]mysql stored procedure to alter column type

In my MySQL setup I have about a dozen database with hundreds of tables where all id fields are defined with type varchar(20).在我的 MySQL 设置中,我有大约十几个数据库,其中包含数百个表,其中所有 id 字段都使用 varchar(20) 类型定义。 Per database there are a few thousand of these fields.每个数据库有几千个这样的字段。 These fields need to be altered into varchar(36).这些字段需要更改为 varchar(36)。

In order to make this happen I have created a stored procedure, that:为了实现这一点,我创建了一个存储过程,即:

  1. gets all appropriate schemas;获取所有适当的模式;
  2. get the tables of the schemas;获取模式表;
  3. loop through all the columns and when the column type = 'varchar(20) alter the column to varchar(36).循环遍历所有列,当列类型 = 'varchar(20) 时将列更改为 varchar(36)。

The content of the procedure is available below.程序内容如下。 But instead of altered column types I get nothing.但是我没有得到任何改变的列类型。 Meaning there is something wrong.意思是有问题。 But what is it?但它是什么?

Can you help me out?你能帮我吗?

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 ;

Your help is appreciated.感谢您的帮助。

Best regards最好的问候

I was in need of these procedures, and see some changes I made, that worked:我需要这些程序,并看到我所做的一些更改,这些更改有效:

CREATE PROCEDURE get_database() BEGIN DECLARE _table_name VARCHAR(255);创建程序 get_database() BEGIN DECLARE _table_name VARCHAR(255); DECLARE finished INTEGER DEFAULT 0; 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;    

END结束

CREATE PROCEDURE get_column(db_name VARCHAR(255), table_name VARCHAR(255)) BEGIN DECLARE _column_name VARCHAR(255); CREATE PROCEDURE get_column(db_name VARCHAR(255), table_name VARCHAR(255)) BEGIN DECLARE _column_name VARCHAR(255); DECLARE finished INTEGER DEFAULT 0; 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;

END结束

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

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