如何批量将数据库中varchar类型统一转换为nvarchar类型?
手动改上千张表和存储过程简直是噩梦!咱们用SQL Server的系统视图来自动化搞定,下面是一步到位的方案,把所有varchar类型转成nvarchar还保留原长度:
一、批量生成表字段的修改脚本
直接通过系统视图遍历所有用户表,自动生成ALTER TABLE语句来修改字段类型:
SELECT 'ALTER TABLE [' + SCHEMA_NAME(t.schema_id) + '].[' + t.name + '] ALTER COLUMN [' + c.name + '] NVARCHAR(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length/2 AS VARCHAR) END + ') ' + CASE WHEN c.is_nullable = 1 THEN 'NULL' ELSE 'NOT NULL' END + ';' AS AlterScript FROM sys.tables t JOIN sys.columns c ON t.object_id = c.object_id JOIN sys.types ty ON c.system_type_id = ty.system_type_id WHERE ty.name = 'varchar' AND t.is_ms_shipped = 0 -- 排除系统表 ORDER BY t.name, c.name;
脚本说明:
- 自动识别所有用户表中的
varchar字段,保留原字段的NULL/NOT NULL属性 - 处理长度逻辑:
varchar的max_length是字节数,nvarchar是字符数,所以自动除以2;如果是varchar(max)则直接转成nvarchar(max) - 生成的脚本可以直接复制到查询窗口执行(务必先在测试环境验证!)
二、批量生成存储过程/函数的修改脚本
通过解析对象的定义文本,替换其中的varchar为nvarchar,自动生成ALTER语句:
SELECT CASE WHEN o.type = 'P' THEN 'ALTER PROCEDURE ' WHEN o.type IN ('FN', 'IF', 'TF') THEN 'ALTER FUNCTION ' ELSE '' END + SCHEMA_NAME(o.schema_id) + '.[' + o.name + '] ' + REPLACE(REPLACE(m.definition, 'varchar(', 'nvarchar('), 'varchar(max)', 'nvarchar(max)') AS AlterScript FROM sys.objects o JOIN sys.sql_modules m ON o.object_id = m.object_id WHERE o.type IN ('P', 'FN', 'IF', 'TF') -- 覆盖存储过程、标量函数、表值函数 AND o.is_ms_shipped = 0 -- 排除系统对象 AND m.definition LIKE '%varchar%'; -- 只处理包含varchar的对象
注意事项:
- 脚本会替换定义中所有
varchar(和varchar(max)为对应的nvarchar,覆盖参数、变量声明和语句中的类型 - 少数极端情况(比如字符串常量里包含
varchar字样)可能误替换,所以生成脚本后一定要抽查核心对象确认正确性 - 嵌套对象或包含动态SQL的存储过程/函数,建议单独检查,避免漏改或误改
关键提醒
- 先备份,再测试:必须在测试环境先执行脚本,验证所有转换正确后再碰生产环境
- 注意性能:修改表字段类型会重建相关索引,尽量在业务低峰期操作
- 检查应用兼容性:转换后要确认应用层是否兼容
nvarchar(比如ORM框架的映射规则是否需要调整) - 人工复查脚本:自动生成的存储过程/函数修改语句可能存在特殊情况,务必复查部分核心对象
内容的提问来源于stack exchange,提问作者Anuj Tamrakar




