SQL Server LIKE运算符中的字符范围和区分大小写列

5
你能为我解释一下为什么以下查询会返回不符合LIKE条件的行。表中的列具有区分大小写的排序规则,因此查询不应该返回任何内容。
CREATE TABLE #temp (col CHAR COLLATE SQL_Latin1_General_CP1_CS_AS);
INSERT INTO #temp VALUES ('A'), ('B'), ('C'), ('D'), ('E');
SELECT * FROM #temp WHERE col LIKE '[b-d]';

任何其他区分大小写的排序(如Latin1_General_100_CS_AS,Polish_100_CS_AS,Modern_Spanish_100_CS_AS)也无法正常工作。据我所知,只有二进制排序集合(Latin1_General_100_BIN2,Modern_Spanish_100_BIN2)可以正常工作。
这个错误仅在使用LIKE条件中的范围时存在。当我将[b-d]更改为[bcd]时,一切正常。
这是数据库引擎的一个bug吗?
我使用的是Microsoft SQL Server 2008(SP3)-10.0.5846.0(X64)企业版(64位)在Windows NT 6.1(Build 7601:Service Pack 1)上。

请参见此处以获取更多信息:https://dev59.com/P17Va4cB1Zd3GeqPFwei - Eugene
2个回答

5
不,这不是一个错误。
语法中的范围不是一个正则表达式。它定义了一个按排序顺序排序的范围。
这些排序规则将AaBbCcDd...YyZz(大小写混合)排序,因此这是一个预期结果。
二进制排序规则将AB .... YZ .... ab ... yz(大写和小写分开)排序,这就是为什么对于这些排序规则它可以正确工作的原因。

这解释了一切。谢谢。 - keiichi
根据您的不区分大小写的示例,[b-d] 应该匹配 d 而不是 D。真的是这样吗?看起来并不是:SELECT 1 WHERE 'D' LIKE '[b-d]' - usr
@usr - 也许我把它搞反了,它先排序大写字母。但原则是正确的。 - Martin Smith
@usr - 已更正。因此需要是 SELECT 1 WHERE 'B' LIKE '[b-d]' COLLATE SQL_Latin1_General_CP1_CS_AS。实际上对于 Latin1_General_CS_AS,情况恰好相反,应该先写小写字母。 - Martin Smith

2
为了展示您在答案中发布的示例的顺序:
CREATE TABLE #temp (col CHAR);
INSERT INTO #temp VALUES ('A'), ('B'), ('C'), ('D'), ('E'), ('a'), ('b'), ('c'), ('d'), ('e');
-- This will work (ABCDEabcde):
SELECT * FROM #temp ORDER BY col COLLATE Latin1_General_BIN
-- These will order letters:
SELECT * FROM #temp ORDER BY col COLLATE Latin1_General_100_CS_AS
SELECT * FROM #temp ORDER BY col COLLATE Polish_100_CS_AS
SELECT * FROM #temp ORDER BY col COLLATE Modern_Spanish_100_CS_AS
SELECT * FROM #temp ORDER BY col COLLATE SQL_Latin1_General_CP1_CS_AS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接