在我的MySQL设置中,我有大约十几个包含数百个表的数据库,其中所有id字段都使用varchar(20)类型定义。每个数据库有几千个这样的字段。这些字段需要更改为varchar(36)。
为了实现这一点,我创建了一个存储过程:
该程序的内容如下。但是没有改变列类型,我什么都没得到。意思是有问题。但它是什么?
你能救我吗?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 ;
感谢您的帮助。
祝你好运
答案 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;
结束