【问题标题】:Case insensitive Predicate in WHERE clause without Changing Collation不更改排序规则的 WHERE 子句中不区分大小写的谓词
【发布时间】:2018-04-27 15:53:53
【问题描述】:

假设我想得到所有姓史密斯的人

SELECT *
FROM   Person
WHERE  LastName = 'Smith'

以上都很好。但是,由于我的数据库排序规则是 CS,因此 LastName 值(如 SmItHsmithSMITH)不会包含在上述结果中。

我可以的

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

这会起作用,但是查询不是 SARGable。但是,问题在于这将导致表/索引扫描而不是查找。

我知道我可以更改列或数据库排序规则,但有没有一种方法可以在不更改任何数据库的情况下使查询 SARGable?

【问题讨论】:

  • 如果操作排序规则是CI,WHERE LastName = 'Smith'会找到所有的case组合
  • 尝试您的第一个查询。默认情况下,sql server 不区分大小写,因此它应该找到所有 smith 大小写组合
  • @marc_s 抱歉,我的错字 - 现在已更正
  • 您应该在问题中添加您的排序规则是 CS 的信息,而不是在评论中。这是非常重要的信息
  • 如果您的排序规则是 CS 并且您想要 CI 搜索,那么您就完蛋了。最接近“没有数据库更改”(例如,没有向后不兼容的更改,尽管您仍然需要更改实际查询)是计算列 AS LastName COLLATE Latin1_General_CI_AS(或类似的)上的索引。显然,这会增加存储空间,但 TANSTAAFL。

标签: sql sql-server


【解决方案1】:

也许 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]'

【讨论】:

    【解决方案2】:

    您可以通过将排序规则放在 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
    

    排序规则也可以用在case语句中。

    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 只是为了证明在包含排序规则后区分大小写。

    【讨论】:

      猜你喜欢
      • 2011-03-18
      • 2015-07-07
      • 2011-05-11
      • 2011-05-23
      • 2019-06-19
      • 2012-01-12
      • 2016-09-03
      • 2010-11-14
      • 2011-06-01
      相关资源
      最近更新 更多