SQL Server 排序规则设置

SQL Server Collation Setting

提问人:Ⲁⲅⲅⲉⲗⲟⲥ 提问时间:8/14/2023 更新时间:8/15/2023 访问量:66

问:

在 SQL Server 中,默认排序规则是 ,以前,我习惯于在每个查询的末尾显式指定排序规则,以便在比较字符串时忽略重音符号。SQL_Latin1_General_CP1_CI_ASSQL_Latin1_General_CP1_CI_AI

现在,我想实现一个通用解决方案,因此,我将数据库排序规则更改为,但除非我显式指定排序规则,否则查询仍然不起作用! 我搜索了一下这个问题,我知道以前使用旧排序规则创建的列也必须更新为新的排序规则,或者必须删除并重新创建!SQL_Latin1_General_CP1_CI_AI

有没有办法在不逐个更新所有列的情况下处理这个问题?


这是我的查询示例 指定排序规则后:

select * from Members where FirstName like '%cafe%' collate SQL_Latin1_General_CP1_CI_AI

在不指定排序规则的情况下:

select * from Members where FirstName like '%cafe%'
sql-server 字符串比较 排序规则不 区分重音

评论

0赞 Thom A 8/14/2023
如果您的列位于不同的排序规则中,则在进行比较时,将使用该列的排序规则。如果您的列处于错误的排序规则中,那么更改它们的排序规则是正确的解决方案,但是,这并不像更改它们那么简单,因为某些依赖对象需要编辑和红色。DROPCREATE
0赞 Ⲁⲅⲅⲉⲗⲟⲥ 8/14/2023
我只想要在比较字符串时忽略重音的最简单方法,仅此而已!如果我找不到任何简单的方法,我将不得不更新所有列的排序规则
0赞 Thom A 8/14/2023
更改列的排序规则是您要做的,因为语法使用是不可 SARGable 的。COLLATE

答:

0赞 Charlieface 8/15/2023 #1

您可以使用以下代码生成脚本来更改所有表中所有列的排序规则:

DECLARE @fromCollation sysname = 'collation_name_here', @toCollation sysname = 'collation_name_here';

DECLARE @sql nvarchar(max);

SELECT
  CONCAT(
    'ALTER TABLE ',
    QUOTENAME(s.name),
    '.',
    QUOTENAME(t.name),
    ' ALTER COLUMN ',
    QUOTENAME(c.name),
    ' ',
    typ.name,
    '(',
    c.max_length,
    ') COLLATE ',
    @toCollation,
    IIF(c.is_nullable = 1, ' NULL', ' NOT NULL')
  )
FROM sys.tables t
JOIN sys.schemas s ON s.schema_id = t.schema_id
JOIN sys.columns c ON c.object_id = t.object_id
JOIN sys.types typ ON typ.user_type_id = c.user_type_id
WHERE c.collation_name = @fromCollation
  AND typ.name IN ('varchar', 'nvarchar', 'char', 'nchar');

如果您有任何非聚集索引,或者任何架构绑定的函数或视图,则需要删除并重新创建它们。

评论

0赞 siggemannen 8/15/2023
这通常远远不足以更改列排序规则,因为索引、内联函数等可能依赖于要更改的列。
0赞 Charlieface 8/15/2023
仅当它们具有其他功能时,更改它就可以了。WITH SCHEMABINDING
0赞 Ⲁⲅⲅⲉⲗⲟⲥ 8/17/2023
@Charlieface,不幸的是,这个解决方案不适合,因为我们有许多与我们需要更新的列相关的索引!
1赞 Charlieface 8/17/2023
可能只是使用一个工具将所有索引和约束编写为删除/创建脚本