【问题标题】:SQL Server Like Query not case sensitiveSQL Server Like Query 不区分大小写
【发布时间】:2014-08-19 20:16:05
【问题描述】:

查询

SELECT  * 
from Table_2  
WHERE  name like ('Joe');

输出

1 100 乔 2 200 乔 3 300 乔伊 4 400 乔

为什么不区分大小写?

【问题讨论】:

  • 不相关但:LIKE 如果您不使用通配符,则没有任何意义。

标签: sql sql-server sql-server-2008 sql-server-2008-r2 sql-server-2012


【解决方案1】:

那是您的数据库配置为不区分大小写。

为了改变这个:

  • 打开SSMSE
  • 右键单击您的数据库并选择属性
  • 在左侧窗格中选择选项
  • Collat​​ion 下的值更改为您当前使用的值,只是使用 CS(区分大小写)而不是 CI(不区分大小写)

例如,如果您正在使用:

  • SQL_Latin1_General_CP1_CI_AS

改成:

  • SQL_Latin1_General_CP1_CS_AS

如果您想进一步了解排序规则,请查看this 线程下接受的答案。

更新:
请注意,正如@BogdanSahlean 所指出的,此解决方案适用于新创建的对象,但不适用于现有的表和列。
来自 MSDN:

您可以更改在 a 中创建的任何新对象的排序规则 使用 ALTER DATABASE 的 COLLATE 子句的用户数据库 陈述。此语句不会更改列的排序规则 在任何现有的用户定义表中。这些可以通过使用 ALTER TABLE 的 COLLATE 子句。

【讨论】:

  • 如何关闭它?
【解决方案2】:

问题:

查询不区分大小写

原因:“名称”列有不区分大小写的 (CI) 排序规则。

解决方案:您必须使用CS 排序规则:SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%'

注意:有数据库排序规则和列级排序规则。而且,还有一个服务器级别的排序规则。

SELECT  DATABASEPROPERTYEX(DB_NAME(), 'Collation') AS DatabaseCollation
/*
-- Sample output (my database)
DatabaseCollation
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/

SELECT  col.collation_name AS ColumnCollation
FROM    sys.columns col
WHERE   col.object_id = OBJECT_ID(N'dbo.Table_2') 
AND     col.name = N'Name'
/*
-- Sample output (my database)
ColumnCollation
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/

仅更改数据库排序规则将不会更改现有用户表和列的排序规则:

此语句不会更改任何列的排序规则 现有的用户定义表。这些可以通过使用 ALTER TABLE 的 COLLATE 子句。

Source

更改数据库排序后,上述查询的输出将是:

/*
DatabaseCollation -- changed
----------------------------
SQL_Latin1_General_CP1_CS_AS
*/

/*
ColumnCollation -- no change
----------------------------
SQL_Latin1_General_CP1_CI_AS
*/

并且,如您所见,Name 列的排序规则仍然是 CI。

此外,更改数据库排序规则只会影响新创建的表和列。 因此,更改数据库排序规则可能会产生奇怪的结果(在我的意见中),因为某些 [N][VAR]CHAR 列将是 CI,而新列将是 CS。

详细解决方案#1:如果只是Name 列的一些查询需要CS,那么我将重写这些查询的WHERE 子句:

SELECT  Name 
FROM    dbo.Table_2
WHERE   Name LIKE 'Joe' AND Name LIKE 'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS

这将使 SQL Server 更改为在列 Name 上执行 Index Seek(在列 Name 上存在索引)。此外,执行计划将包含隐式转换(请参阅 Index SeekPredicate 属性),因为以下谓词 Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS

详细解决方案 #2:如果列 Name 的所有查询都需要是 CS,那么我将仅更改列 Name 的排序规则,因此:

-- Drop all objects that depends on this column (ex. indexes, constraints, defaults)
DROP INDEX IX_Table_2_Name ON dbo.Table_2

-- Change column's collation
ALTER TABLE dbo.Table_2
ALTER COLUMN Name VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CS_AS
-- Replace VARCHAR(50) with proper data type and max. length
-- Replace COLLATE SQL_Latin1_General_CP1_CS_AS with the right CS collation

-- Recreate all objects that depends on column Name (ex. indexes, constraints, defaults)
CREATE INDEX IX_Table_2_Name ON dbo.Table_2 (Name)

-- Test query
SELECT  Name 
FROM    dbo.Table_2
WHERE   Name LIKE 'Joe'

【讨论】:

    【解决方案3】:

    如果您希望您的查询仅在少数情况下区分大小写,那么您可以尝试以下查询:

    SELECT *
    FROM TableName
    where Col1 = 'abcdEfhG' COLLATE SQL_Latin1_General_CP1_CS_AS
    

    只需在查询前添加“COLLATE SQL_Latin1_General_CP1_CS_AS”

    【讨论】:

      猜你喜欢
      • 2013-09-22
      • 1970-01-01
      • 2016-01-17
      • 2013-02-04
      • 1970-01-01
      • 2015-07-23
      • 2012-05-13
      • 1970-01-01
      • 2015-06-29
      相关资源
      最近更新 更多