【sqlserver】修改nvarchar类型为varchar脚本
使用之前建议用测试库测试,或者对主库进行备份
不删除索引无法修改某些使用了索引的列,先把查询出来的索引备份,
即SELECT IndexCreateSQL FROM @IndexCreateSQL;
USE xxx_database;
GO-- 声明变量
DECLARE @sql NVARCHAR(MAX) = N'';
DECLARE @alter_sql NVARCHAR(MAX);
DECLARE @IndexDropSQL TABLE (IndexDropSQL NVARCHAR(MAX));
DECLARE @IndexCreateSQL TABLE (IndexCreateSQL NVARCHAR(MAX));
DECLARE @AlterSQL TABLE (AlterSQL NVARCHAR(MAX));-- 查找所有表的 nvarchar 类型字段,排除主键字段、唯一约束字段和系统表
INSERT INTO @AlterSQL (AlterSQL)
SELECT 'ALTER TABLE ' + QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) + ' ALTER COLUMN ' + QUOTENAME(COLUMN_NAME) + CASE WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN ' TEXT'ELSE ' VARCHAR(' + CAST(CHARACTER_MAXIMUM_LENGTH * 2 AS NVARCHAR(10)) + ')'END + ';'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE = 'nvarchar' AND CHARACTER_MAXIMUM_LENGTH IS NOT NULLAND COLUMN_NAME NOT IN (-- 排除主键字段SELECT c.name FROM sys.tables tINNER JOIN sys.indexes i ON t.object_id = i.object_idINNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_idINNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_idWHERE i.is_primary_key = 1)AND COLUMN_NAME NOT IN (-- 排除唯一约束字段SELECT c.name FROM sys.tables tINNER JOIN sys.indexes i ON t.object_id = i.object_idINNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_idINNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_idWHERE i.is_unique = 1 OR i.is_unique_constraint = 1)AND TABLE_SCHEMA != 'sys' -- 排除系统表AND COLUMN_NAME not in('PatientId','Founder','PatientNo','Modifier','GroupId');-- 查找每个表的所有非主键、非唯一约束索引并生成删除和重新创建的SQL语句
INSERT INTO @IndexDropSQL (IndexDropSQL)
SELECT'DROP INDEX ' + QUOTENAME(i.name) + ' ON ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + '.' + QUOTENAME(OBJECT_NAME(i.object_id)) + ';'
FROM sys.indexes i
INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
WHERE i.is_primary_key = 0 -- 排除主键索引AND i.is_unique = 0 -- 排除唯一索引AND i.is_unique_constraint = 0 -- 排除唯一约束AND OBJECT_SCHEMA_NAME(i.object_id) != 'sys'; -- 排除系统表INSERT INTO @IndexCreateSQL (IndexCreateSQL)
SELECT'CREATE INDEX ' + QUOTENAME(i.name) + ' ON ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + '.' + QUOTENAME(OBJECT_NAME(i.object_id)) + '(' + STUFF((SELECT ', ' + QUOTENAME(c.name)FROM sys.index_columns ic2INNER JOIN sys.columns c2 ON ic2.object_id = c2.object_id AND ic2.column_id = c2.column_idWHERE ic2.object_id = i.object_id AND ic2.index_id = i.index_idORDER BY ic2.index_column_idFOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') + ');'
FROM sys.indexes i
INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
WHERE i.is_primary_key = 0 -- 排除主键索引AND i.is_unique = 0 -- 排除唯一索引AND i.is_unique_constraint = 0 -- 排除唯一约束AND OBJECT_SCHEMA_NAME(i.object_id) != 'sys'; -- 排除系统表-- 输出删除索引的SQL语句
SELECT IndexDropSQL FROM @IndexDropSQL;-- 输出创建索引的SQL语句
SELECT IndexCreateSQL FROM @IndexCreateSQL;--输出修改列的SQL语句
SELECT AlterSQL FROM @AlterSQL;-- 执行修改列的SQL语句
WHILE EXISTS (SELECT 1 FROM @AlterSQL)
BEGINSELECT TOP 1 @alter_sql = AlterSQL FROM @AlterSQL;PRINT '执行修改列的SQL语句:' + @alter_sql;EXEC(@alter_sql);DELETE TOP (1) FROM @AlterSQL;
END