不更改排序规则的WHERE子句中不区分大小写的谓词

时间:2017-11-14 16:03:49

标签: sql sql-server

说我想要所有姓史密斯的人

SELECT *
FROM   Person
WHERE  LastName = 'Smith'

以上情况很好。但是,由于我的数据库排序规则是CS,因此LastNameSmItHsmithSMITH值不会包含在上述结果中。

我能做到

SELECT *
FROM   Person
WHERE  UPPER(LastName) = 'SMITH' 

哪个可行,但查询不是SARGable。但是,问题在于这将导致表/索引扫描而不是搜索。

我知道我可以更改列或数据库排序规则,但有没有办法让查询SARGable而不进行任何数据库更改?

2 个答案:

答案 0 :(得分:1)

您可以通过将查询放在where子句之后来更改查询中的排序规则。您还可以混合where子句中使用的排序规则。 (以下示例除了演示使用两种不同的排序规则外毫无意义。)

SELECT  *
  FROM  sys.objects AS o
  WHERE UPPER( o.name ) = o.name COLLATE SQL_Latin1_General_CP1_CS_AS
        AND o.name = o.name COLLATE SQL_Latin1_General_CP1_CI_AS

整理测试也可用于案例陈述。

SELECT  o.name,
        CASE
          WHEN UPPER( o.name ) = o.name COLLATE SQL_Latin1_General_CP1_CS_AS
            THEN 'Upper Case'
          WHEN LOWER( o.name ) = o.name COLLATE SQL_Latin1_General_CP1_CS_AS
            THEN 'Lower Case'
          ELSE 'Mixed Case'
        END
  FROM  sys.objects AS o
  WHERE o.is_ms_shipped = 0
;

请注意,使用UPPER / LOWER只是为了证明包含校对后的大小写敏感性。

答案 1 :(得分:0)

也许T-SQL模式匹配会有所帮助: https://technet.microsoft.com/en-us/library/ms187489(v=sql.105).aspx

它不漂亮,但这应该有效:

SELECT *
FROM Person
WHERE LastName LIKE '[Ss][Mm][Ii][Tt][Hh]'

我不能100%确定SQL Server是否能够使用这种查询的索引。

对于索引来说,这样的事情可能更好:

SELECT *
FROM Person
WHERE LastName LIKE 'S[Mm][Ii][Tt][Hh]'
OR LastName LIKE 's[Mm][Ii][Tt][Hh]'