无法解决 SELECT 语句中 CASE 运算符中出现的“Polish_CI_AS”和“SQL_Latin1_General_CP1_CI_AS”之间的排序规则冲突

Cannot resolve collation conflict between "Polish_CI_AS" and "SQL_Latin1_General_CP1_CI_AS" in CASE operator occurring in SELECT statement

提问人:user3057544 提问时间:9/14/2023 最后编辑:Dale Kuser3057544 更新时间:9/14/2023 访问量:223

问:

我的查询从同一服务器上的两个数据库中选择数据。

服务器排序规则为 。SQL_Latin1_General_CP1_CI_AS

db1 归类是Polish_CI_AS

db2 排序规则是,但我将其更改为使用:SQL_Latin1_General_CP1_CI_ASPolish_CI_AS

ALTER DATABASE [db2] COLLATE Polish_CI_AS;

现在,当我运行此脚本时:

SELECT name, collation_name FROM sys.databases; 

我可以看到两个数据库具有相同的排序规则。Polish_CI_AS

但我仍然收到以下错误:

无法解决 SELECT 语句中 CASE 运算符中“Polish_CI_AS”和“SQL_Latin1_General_CP1_CI_AS”之间的排序规则冲突

在下面的查询片段中:

CASE
    WHEN 1=1 THEN db1.colX
    WHEN 1=1 THEN db2.colY
END AS TEST

但是,当我添加“COLLATE Polish_CI_AS”时,例如:

CASE
    WHEN 1=1 THEN db1.colX COLLATE Polish_CI_AS
    WHEN 1=1 THEN db2.colY
END AS TEST

CASE
    WHEN 1=1 THEN db1.colX
    WHEN 1=1 THEN db2.colY COLLATE Polish_CI_AS
END AS TEST

然后它起作用了。

我还指出,它可以是任何排序规则,例如:

CASE
    WHEN 1=1 THEN db1.colX
    WHEN 1=1 THEN db2.colY COLLATE ESTONIAN_100_BIN 
END AS TEST

它仍然有效。

问题: 为什么在两个数据库中具有相同的排序规则,查询不起作用,但在向其添加任何排序规则后,它起作用了?

sql-server sql-server 排序规则

评论

3赞 siggemannen 9/14/2023
数据库排序规则更改不会更改表列的排序规则,它需要手动更改,这可能是一个有点繁琐的过程,因为索引等依赖于排序规则
0赞 Panagiotis Kanavos 9/14/2023
实际查询是什么,为什么要使用它?为什么? 将删除错误,但阻止使用任何索引。即使在 nvarchar 列中,排序规则也会影响排序顺序以及索引的生成和搜索方式。似乎此代码段是包罗万象查询的一部分,即使没有排序规则问题,该查询也会很慢CASEWHEN 1=1 COLLATE
2赞 FAB 9/14/2023
我假设 1=1 只是为了能够显示代码片段,与实际查询 Panagiotis 无关
0赞 Panagiotis Kanavos 9/14/2023
@FAB我不太确定。 在简单动态 SQL 代码中使用,以允许 WHERE 中有 0 个或多个条件。但是,即使具有有意义的条件,查询也会出现相同的问题。1=1

答:

1赞 Martin Smith 9/14/2023 #1

db2.colY 仍将采用波兰语排序规则(如 所示)。更改数据库排序规则不会影响预先存在的列的排序规则。sys.columns

添加时,不再具有相同优先级的冲突排序规则,而是处于“显式标签”与“隐式标签”案例中COLLATE ESTONIAN_100_BIN

显式标签...优先于 Implicit 标签

评论

1赞 Panagiotis Kanavos 9/14/2023
应该注意的是,这会阻止使用使用列的排序规则创建的索引。错误消失了,但成本仍然存在COLLATE
0赞 Martin Smith 9/14/2023
没错,但在这种情况下,无论如何,索引寻求的都无济于事CASE WHEN 1=1 THEN db1.colX WHEN 1=1 THEN db2.colY END
0赞 Panagiotis Kanavos 9/14/2023
这看起来像一个糟糕的 catch-all 查询(如果不是组合 catch-all 和动态 sql),其中排序规则只是问题之一。
0赞 Martin Smith 9/14/2023
可能是。我们没有理由认为这在条款中。关于为什么添加显式排序规则会使错误消失的问题仍然是一个有效的问题。如果您想就其他问题咨询 OP,请在 Q 的评论中进行,而不是这个答案,这样我就不会收到有关它的通知WHERE
0赞 Charlieface 9/15/2023
@MartinSmith我实际上认为这将在 a 中使用索引,因为会被省略 dbfiddle.uk/5CMXIithWHERECASE