修改SQL Server数据库排序规则后仍需显式指定,如何批量处理列排序规则?
SQL Server数据库排序规则变更后无需逐列手动更新的解决方案
问题背景
数据库默认排序规则原为SQL_Latin1_General_CP1_CI_AS,为实现字符串比较时忽略重音,此前需在每个查询末尾显式指定SQL_Latin1_General_CP1_CI_AI排序规则。将数据库排序规则修改为SQL_Latin1_General_CP1_CI_AI后,未显式指定排序规则的查询仍不生效——原因是旧排序规则创建的列,不会自动继承新的数据库排序规则。
是否存在无需逐个更新列的解决办法?
没有完全无需修改列就能让现有查询自动生效的方案,但可以通过批量脚本自动更新所有目标列,避免手动逐个操作:
1. 批量生成列排序规则修改脚本
通过查询系统视图,自动生成所有字符类型列(char/varchar/nchar/nvarchar)的修改语句,步骤如下:
- 执行以下SQL生成批量修改脚本:
SELECT 'ALTER TABLE [' + SCHEMA_NAME(t.schema_id) + '].[' + t.name + '] ALTER COLUMN [' + c.name + '] ' + TYPE_NAME(c.system_type_id) + CASE WHEN c.max_length = -1 THEN '(MAX)' ELSE '(' + CAST(c.max_length AS VARCHAR) + ')' END + ' COLLATE SQL_Latin1_General_CP1_CI_AI ' + CASE WHEN c.is_nullable = 1 THEN 'NULL' ELSE 'NOT NULL' END + ';' FROM sys.columns c JOIN sys.tables t ON c.object_id = t.object_id WHERE c.collation_name = 'SQL_Latin1_General_CP1_CI_AS' AND TYPE_NAME(c.system_type_id) IN ('char', 'varchar', 'nchar', 'nvarchar')
- 运行生成的所有
ALTER TABLE语句,即可一次性将所有旧规则列更新为新排序规则。
2. 临时替代方案(不修改列的场景)
若暂时无法修改列排序规则,可采用以下临时方案,但不推荐作为长期解决方案:
- 创建带排序规则的视图:为目标列指定新排序规则,后续查询视图即可无需显式指定规则,示例:
CREATE VIEW vw_Members AS SELECT FirstName COLLATE SQL_Latin1_General_CP1_CI_AI AS FirstName, LastName COLLATE SQL_Latin1_General_CP1_CI_AI AS LastName -- 其他列按此格式添加 FROM Members
此方案需维护视图,且可能引发隐式转换影响查询性能。
- 连接级指定排序规则:在查询中使用
COLLATE DATABASE_DEFAULT,让查询默认使用当前数据库的排序规则,示例:
SELECT * FROM Members WHERE FirstName LIKE '%cafe%' COLLATE DATABASE_DEFAULT
此方案仅对当前连接生效,仍存在隐式转换的性能风险。
总结
最彻底且推荐的方案是通过批量脚本更新列排序规则,这是唯一能一劳永逸解决问题的方式——因为列的排序规则是存储在列元数据中的,不会随数据库排序规则的变更自动同步。
内容的提问来源于stack exchange,提问作者Ⲁⲅⲅⲉⲗⲟⲥ
相关产品推荐
相关产品推荐

