我想更改数据库所有表的所有列的排序规则。在堆栈溢出的其他帖子中,我找到了这个脚本:(post)
SELECT 'ALTER TABLE [' + SYSOBJECTS.Name + '] ALTER COLUMN [' + SYSCOLUMNS.Name + '] ' +
SYSTYPES.name +
CASE systypes.NAME
WHEN 'text' THEN ' '
ELSE
'(' + RTRIM(CASE SYSCOLUMNS.length
WHEN -1 THEN 'MAX'
ELSE CONVERT(CHAR,SYSCOLUMNS.length)
END) + ') '
END
+ ' ' + ' COLLATE Latin1_General__CI_AI ' + CASE ISNULLABLE WHEN 0 THEN 'NOT NULL' ELSE 'NULL' END
FROM SYSCOLUMNS , SYSOBJECTS , SYSTYPES
WHERE SYSCOLUMNS.ID = SYSOBJECTS.ID
AND SYSOBJECTS.TYPE = 'U'
AND SYSTYPES.Xtype = SYSCOLUMNS.xtype
AND SYSCOLUMNS.COLLATION IS NOT NULL
AND NOT ( sysobjects.NAME LIKE 'sys%' )
AND NOT ( SYSTYPES.name LIKE 'sys%' )
GO
然而,当我看到列的整理时,我发现整理是旧的整理。
实际的整理是AS,所以我可以拥有“ANIMAL”和“ÁNIMAL”。当我执行脚本时,我没有收到任何错误。我认为我会得到一个错误,因为新的排序规则是AI。所以这让我觉得脚本什么都不做。
为什么我可以更改数据库中所有表的所有列的排序规则?
感谢。
答案 0 :(得分:75)
试试这个 -
<强>查询:强>
DECLARE @collate SYSNAME
SELECT @collate = 'Cyrillic_General_CS_AS'
SELECT
'[' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + '] -> ' + c.name
, 'ALTER TABLE [' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + ']
ALTER COLUMN [' + c.name + '] ' +
UPPER(t.name) +
CASE WHEN t.name NOT IN ('ntext', 'text')
THEN '(' +
CASE
WHEN t.name IN ('nchar', 'nvarchar') AND c.max_length != -1
THEN CAST(c.max_length / 2 AS VARCHAR(10))
WHEN t.name IN ('char', 'varchar') AND c.max_length != -1
THEN CAST(c.max_length AS VARCHAR(10))
WHEN t.name IN ('nchar', 'nvarchar', 'char', 'varchar') AND c.max_length = -1
THEN 'MAX'
ELSE CAST(c.max_length AS VARCHAR(10))
END + ')'
ELSE ''
END + ' COLLATE ' + @collate +
CASE WHEN c.is_nullable = 1
THEN ' NULL'
ELSE ' NOT NULL'
END
FROM sys.columns c
JOIN sys.objects o ON c.[object_id] = o.[object_id]
JOIN sys.types t ON c.system_type_id = t.system_type_id AND c.user_type_id = t.user_type_id
WHERE t.name IN ('char', 'varchar', 'text', 'nvarchar', 'ntext', 'nchar')
AND c.collation_name != @collate
AND o.[type] = 'U'
<强>输出:强>
-------------------------------------------------- ------------------------------------------------------------------------------------------------------------------
[dbo].[CategoryType] -> CategoryTypeCD ALTER TABLE [dbo].[CategoryType] ALTER COLUMN [CategoryTypeCD] VARCHAR(20) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[Employee] -> TabelNumber ALTER TABLE [dbo].[Employee] ALTER COLUMN [TabelNumber] VARCHAR(12) COLLATE Cyrillic_General_CI_AS NULL
[dbo].[Supplement] -> WorkFactorCD ALTER TABLE [dbo].[Supplement] ALTER COLUMN [WorkFactorCD] VARCHAR(50) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[Surcharge] -> WorkFactorCD ALTER TABLE [dbo].[Surcharge] ALTER COLUMN [WorkFactorCD] VARCHAR(50) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[Surcharge] -> Condition ALTER TABLE [dbo].[Surcharge] ALTER COLUMN [Condition] NVARCHAR(MAX) COLLATE Cyrillic_General_CI_AS NULL
[dbo].[WorkFactor] -> WorkFactorCD ALTER TABLE [dbo].[WorkFactor] ALTER COLUMN [WorkFactorCD] VARCHAR(50) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[WorkFactor] -> Name ALTER TABLE [dbo].[WorkFactor] ALTER COLUMN [Name] NVARCHAR(200) COLLATE Cyrillic_General_CI_AS NOT NULL
[dbo].[WorkOut] -> WorkShiftCD ALTER TABLE [dbo].[WorkOut] ALTER COLUMN [WorkShiftCD] NVARCHAR(40) COLLATE Cyrillic_General_CI_AS NULL
[dbo].[WorkOut] -> AbsenceCode ALTER TABLE [dbo].[WorkOut] ALTER COLUMN [AbsenceCode] VARCHAR(50) COLLATE Cyrillic_General_CI_AS NULL
[dbo].[WorkOut] -> PaymentType ALTER TABLE [dbo].[WorkOut] ALTER COLUMN [PaymentType] CHAR(4) COLLATE Cyrillic_General_CI_AS NULL
答案 1 :(得分:7)
我发布了上述答案的编辑内容,该编辑针对char和varchar长度,因为我之前的编辑看起来被拒绝了。
DECLARE @collate SYSNAME
SELECT @collate = 'Cyrillic_General_CS_AS'
SELECT
'[' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + '] -> ' + c.name
, 'ALTER TABLE [' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + ']
ALTER COLUMN [' + c.name + '] ' +
UPPER(t.name) +
CASE WHEN t.name NOT IN ('ntext', 'text')
THEN '(' +
CASE
WHEN t.name IN ('nchar', 'nvarchar') AND c.max_length != -1
THEN CAST(c.max_length / 2 AS VARCHAR(10))
WHEN t.name IN ('char', 'varchar') AND c.max_length != -1
THEN CAST(c.max_length AS VARCHAR(10))
WHEN t.name IN ('nchar', 'nvarchar', 'char', 'varchar') AND c.max_length = -1
THEN 'MAX'
ELSE CAST(c.max_length AS VARCHAR(10))
END + ')'
ELSE ''
END + ' COLLATE ' + @collate +
CASE WHEN c.is_nullable = 1
THEN ' NULL'
ELSE ' NOT NULL'
END
FROM sys.columns c WITH(NOLOCK)
JOIN sys.objects o WITH(NOLOCK) ON c.[object_id] = o.[object_id]
JOIN sys.types t WITH(NOLOCK) ON c.system_type_id = t.system_type_id AND c.user_type_id = t.user_type_id
WHERE t.name IN ('char', 'varchar', 'text', 'nvarchar', 'ntext', 'nchar')
AND c.collation_name != @collate
AND o.[type] = 'U'
答案 2 :(得分:5)
我已将各种不同来源的脚本放在一起,删除依赖项会更新排序规则,然后重新创建依赖对象。这解决了更新具有依赖项(索引,外键约束等)的列的排序规则的问题。
dynamic-component
答案 3 :(得分:2)
感谢大家的建议,在将我的数据库从SQL Server 2008 R2迁移到2014时,它对我有很大帮助
注意:部分结果查询包含无效的VARCHAR( - ),我将其更改为VARCHAR(MAX),并且工作正常。
更改排序规则的步骤:
答案 4 :(得分:2)
虽然其他方法都不适合我,this article by Douglas P. Castilho为我提供了一个完整的解决方案。我正在分享它,以防它帮助任何人。
C:\ Program Files \ Microsoft SQL Server \ MSSQL11.MSSQLSERVER \ MSSQL \ Binn
sqlservr -m -T4022 -T3659 -q&#34; [输入整理名称]&#34;
那就是它。
答案 5 :(得分:1)
在执行此操作之前,请先阅读本文。 https://www.mssqltips.com/sqlservertip/3221/how-to-change-the-collation-of-a-sql-server-column/
阅读上述文章后,请确保从数据库中删除了以下引用。
在您忘记更改数据库归类后,点击数据库中的以下脚本。
DECLARE @collate nvarchar(100);
DECLARE @schema_name nvarchar(255);
DECLARE @table_name nvarchar(255);
DECLARE @column_name nvarchar(255);
DECLARE @column_id int;
DECLARE @data_type nvarchar(255);
DECLARE @max_length int;
DECLARE @is_nullable bit;
DECLARE @sql nvarchar(max);
DECLARE @sql_column nvarchar(max);
SET @collate = 'SQL_Latin1_General_CP1_CI_AS';
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE local_change_cursor CURSOR FOR
SELECT SCHEMA_NAME(t.schema_id) schemaname,
t.name table_name
, c.name column_name
, s.Name data_type
, c.max_length
, c.is_nullable
, c.column_id
FROM sys.tables t INNER JOIN
sys.columns c ON c.object_id=t.object_id INNER JOIN
sys.types s ON s.user_type_id=c.user_type_id
WHERE
(c.collation_name LIKE 'SQL_Latin1_General_CP1254_CI_AS' OR c.collation_name LIKE 'Turkish_CI_AS') AND
t.type like 'U'
AND t.name not like 'spt%'
AND t.name not like 'MSrep%'
AND c.collation_name is NOT NULL
order by schemaname
OPEN local_change_cursor
FETCH NEXT FROM local_change_cursor
INTO @schema_name,@table_name, @column_name, @data_type, @max_length,@is_nullable, @column_id
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @nullable nvarchar(255),
@length varchar(10);
IF @is_nullable = 0
BEGIN
SET @nullable = ' NOT NULL';
END
ELSE
BEGIN
SET @nullable = ' NULL';
END
IF @data_type IN ('nchar', 'nvarchar') AND @max_length != -1
BEGIN
SET @length= CAST(@max_length / 2 AS VARCHAR(10));
END
ELSE IF @data_type IN ('char', 'varchar') AND @max_length != -1
BEGIN
SET @length= CAST(@max_length AS VARCHAR(10));
END
ELSE IF @data_type IN ('nchar', 'nvarchar', 'char', 'varchar') AND @max_length = -1
BEGIN
SET @length= 'MAX';
END
ELSE
BEGIN
SET @length= CAST(@max_length AS VARCHAR(10));
END
BEGIN TRY
IF @schema_name <> 'dbo'
BEGIN
SET @sql = 'ALTER TABLE ['+ @schema_name +'].[' + @table_name + '] ALTER COLUMN [' + @column_name + '] ' + @data_type + '(' + @length + ') COLLATE ' + @collate + ''+ @nullable+' '
PRINT @sql
EXEC sp_executesql @sql
END
END TRY
BEGIN CATCH
PRINT 'ERROR: Some index or constraint rely on the column' + @column_name + '. No conversion possible.'
PRINT @sql
END CATCH
FETCH NEXT FROM local_change_cursor
INTO @schema_name,@table_name, @column_name, @data_type, @max_length,@is_nullable, @column_id
END
CLOSE local_change_cursor
DEALLOCATE local_change_cursor
END
GO
答案 6 :(得分:0)
对于正在使用PHPMyAdmin寻找该解决方案的任何人,“数据库操作”选项卡底部都有一个选项(首先单击数据库,然后在顶部工具栏上单击“操作”选项卡);向下滚动到排序规则框,选择一个排序规则,选中两个复选框(选中第一个时出现一个复选框):
似乎基本上像发布的脚本那样运行脚本;控制台显示最终执行的命令:
ALTER TABLE `DB_NAME`.`LAST_TABLE_IN_DB`DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci