[英]Change the Datatype of a Column in the entire Database - MySQL
我是 MySQL 新手。 我设计了几个具有 Char 数据类型的表。 现在我想将所有 char 数据类型列更改为具有 Char 中提到的相应大小的 Varchar。
For example.
Existing - Phone Char(10)
Expected - Phone Varchar(10)
大约有 50 多张桌子。 我知道如何更改每个表和列的数据类型,但是有没有更好的方法可以一次性更改数据类型。
如果你不能写一个脚本来完成这项工作,那就写一个脚本来写一个脚本来完成这项工作!
你想要一堆 ALTER TABLE 语句:
SET SESSION group_concat_max_len = 1000000; -- Bumps the limit of 1028
SELECT GROUP_CONCAT(
CONCAT(
'ALTER TABLE `',
table_name,
'` MODIFY COLUMN `',
column_name,
'` VARCHAR(',
character_maximum_length,
')'
)
SEPARATOR ';\n') your_alter_statements
FROM information_schema.columns
WHERE table_schema = 'concrete'
AND data_type = 'char';
这将导致:
ALTER TABLE `table1` MODIFY COLUMN `col1` VARCHAR(10);
ALTER TABLE `table1` MODIFY COLUMN `col2` VARCHAR(10);
ALTER TABLE `table2` MODIFY COLUMN `col1` VARCHAR(10);
ALTER TABLE `table3` MODIFY COLUMN `col1` VARCHAR(10);
ALTER TABLE `table3` MODIFY COLUMN `col2` VARCHAR(10);
运行它,你可以早点回家!
更新:通过添加group_concat_max_len
停止截断。 根据列长度使长度动态化。
MySQL只有一种衬垫解决方案:
SELECT 'ALTER TABLE ',TABLE_NAME, ' MODIFY COLUMN ',COLUMN_NAME, CONCAT(' VARCHAR(', CHARACTER_MAXIMUM_LENGTH, ');')
FROM INFORMATION_SCHEMA.COLUMNS where DATA_TYPE = 'char' AND TABLE_SCHEMA='concrete'
以上查询将返回所有ALTER TABLE
语句,示例如下:
ALTER TABLE tablename1 MODIFY COLUMN col_name1 VARCHAR(17);
ALTER TABLE tablename2 MODIFY COLUMN col_name2 VARCHAR(17);
ALTER TABLE tablename3 MODIFY COLUMN col_name3 VARCHAR(60);
复制结果行并执行,这样您就可以更早回家。
此外,以下是 PHP/MySQL 解决方案:
// Initialise Connection
define('DB_HOST', 'HOST_NAME_HERE');
define('DB_NAME', 'DB_NAME_HERE');
define('DB_USER_NAME', 'DB_USER_NAME_HERE');
define('DB_PASSWORD', 'DB_PASSWORD_HERE');
$pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER_NAME, DB_PASSWORD, [
PDO::ATTR_PERSISTENT => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
]);
// Get a list of CHAR columns
$sql = "SELECT TABLE_NAME, COLUMN_NAME, CHARACTER_MAXIMUM_LENGTH, IS_NULLABLE, COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS where DATA_TYPE = 'char' AND TABLE_SCHEMA='" . DB_NAME . "'";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Change CHAR to VARCHAR
foreach ($data as $rec) {
$ddq = 'ALTER TABLE ' . $rec['TABLE_NAME'] . ' CHANGE ' . $rec['COLUMN_NAME'] . ' ' . $rec['COLUMN_NAME'] . ' VARCHAR(' .
$rec['CHARACTER_MAXIMUM_LENGTH'] . ') ' . ($rec['IS_NULLABLE'] == 'YES' ? 'NULL' : 'NOT NULL') . (isset($rec['COLUMN_DEFAULT']) ? " DEFAULT '{$rec['COLUMN_DEFAULT']}'" : '');
$pdo->query($ddq);
}
在分析网络后,我得到了答案并使用此查询更改了数据类型。
select
concat('ALTER TABLE ', table_name,' MODIFY COLUMN ', column_name,' ', REPLACE (column_type, 'char', 'varchar'),';')
from information_schema.columns
where
data_type='char'
and table_schema='DBName';
如果您的字段是 PK(例如,'id' smallint unsigned),并且其他一些表对此 PK 具有外键约束,请使用此查询。
注意:对于现代 mysql 服务器,从变量 -> sql 模式中删除 ONLY_FULL_GROUP_BY,默认情况下它包含:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
然后插入并执行这个查询:
SET group_concat_max_len = 10000;
SET @database_name = "database1";
SET @table_name = "table1";
SET @change = "mediumint unsigned";
SELECT DISTINCT
`table_name`,
`column_name`,
`constraint_name`,
`referenced_table_name`,
`referenced_column_name`,
CONCAT(
GROUP_CONCAT('ALTER TABLE `',table_name,'` DROP FOREIGN KEY `',constraint_name, '`' SEPARATOR ';'),
';',
GROUP_CONCAT('ALTER TABLE `',table_name,'` CHANGE `',column_name,'` `',column_name,'` ',@change SEPARATOR ';'),
';',
CONCAT('ALTER TABLE `',@table_name,'` CHANGE `',referenced_column_name,'` `',referenced_column_name,'` ',@change, ' NOT NULL AUTO_INCREMENT'),
';',
GROUP_CONCAT('ALTER TABLE `',table_name,'` ADD CONSTRAINT `',constraint_name,'` FOREIGN KEY(',column_name,') REFERENCES ',referenced_table_name,'(',referenced_column_name,')' SEPARATOR ';'),
';'
) AS query
FROM `information_schema`.`key_column_usage`
WHERE `referenced_table_name` IS NOT NULL
AND `referenced_column_name` IS NOT NULL
AND `constraint_schema` = @database_name
AND `referenced_table_name` = @table_name
GROUP BY `referenced_table_name`;
注意:选中额外选项以显示结果中字段的全文。 然后复制并执行所有生成的查询。 恢复变量中的 ONLY_FULL_GROUP_BY。
享受!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.