简体   繁体   English

SQL Server Like Query不区分大小写

[英]SQL Server Like Query not case sensitive

Query 询问

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

Output 产量

1   100 Joe
2   200 JOE
3   300 jOE
4   400 joe

Why is it not case sensitive? 为什么它不区分大小写?

Problem: 问题:

Query not case sensitive 查询不区分大小写

Cause: Column 'Name' has a case-insensitive ( CI ) collation. 原因:列“名称”具有不区分大小写( CI )排序规则。

Solution: You have to use a CS collation: SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%' . 解决方案:您必须使用CS排序规则: SELECT * FROM fn_helpcollations() WHERE description LIKE N'%case-sensitive%'

Note: There is a database collation and column level collation. 注意:存在数据库排序规则和列级排序规则。 And, there is, also, a server level collation. 而且,还有一个服务器级别的排序规则。

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
*/

Simply changing database collation will NOT change the collation for existing user tables and columns: 简单地更改数据库排序规则不会更改现有用户表和列的排序规则:

This statement does not change the collation of the columns in any existing user-defined tables. 此语句不会更改任何现有用户定义表中列的排序规则。 These can be changed by using the COLLATE clause of ALTER TABLE. 可以使用ALTER TABLE的COLLATE子句更改这些内容。

Source 资源

After changing database collation , the output of above queries will be: 更改数据库归类后 ,上述查询的输出将为:

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

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

and, as you can see the collation of column Name remains CI. 并且,正如您所看到的,列Name的排序规则仍为CI。

More, changing database collation will affect only the new created tables and columns. 此外,更改数据库归类将仅影响新创建的表和列。 Thus, changing database collation could generate strange results (in my opinion ) because some [N][VAR]CHAR columns will be CI and the new columns will be CS. 因此,更改数据库归类可能会产生奇怪的结果(在我看来 ),因为一些[N][VAR]CHAR列将是CI,新列将是CS。

Detailed solution #1: if just some queries for column Name need to be CS then I will rewrite WHERE clause of these queries thus: 详细的解决方案#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

在此输入图像描述

This will give a change to SQL Server to do an Index Seek on column Name (in there is an index on column Name ). 这将使更改SQL服务器做一个Index Seek对列Name (中则列索引Name )。 Also, the execution plan will include an implicit conversion (see Predicate property for Index Seek ) because of following predicate Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS . 此外,执行计划将包括隐式转换(请参阅Index Seek Predicate属性),因为以下谓词Name = N'Joe' COLLATE SQL_Latin1_General_CP1_CS_AS

Detailed solution #2: if all queries for column Name need to be CS then I will change the collation only for column Name thus: 详细解决方案#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'

在此输入图像描述

If you want your query to be case sensitive on few occasions only, then you can try below query: 如果您希望查询仅在少数情况下区分大小写,那么您可以尝试以下查询:

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

Just add "COLLATE SQL_Latin1_General_CP1_CS_AS" in front of the query. 只需在查询前添加“COLLATE SQL_Latin1_General_CP1_CS_AS”即可

That is your DB is configured to be case insensitive. 这是您的数据库配置为不区分大小写。

In order to change this: 为了改变这个:

  • Open SSMSE . 打开SSMSE
  • Right Click on your DB and select Properties 右键单击数据库,然后选择“ 属性”
  • Select Options in the left pane. 在左窗格中选择“ 选项 ”。
  • Change the value under Collation to the same value you are currently using, just with CS (Case sensitive) instead of CI (Case Insensitive) Collat​​ion下的值更改为您当前使用的相同值,仅使用CS(区分大小写)而不是CI(Case Insensitive)

For example, If you are using: 例如,如果您正在使用:

  • SQL_Latin1_General_CP1_ CI _AS SQL_Latin1_General_CP1_ CI _AS

Change it to: 将其更改为:

  • SQL_Latin1_General_CP1_ CS _AS SQL_Latin1_General_CP1_ CS _AS

If you want to understand a bit more about collations, take a look at the accepted answer under this thread. 如果您想了解有关排序规则的更多信息,请查看主题下的已接受答案。

在此输入图像描述

Update: 更新:
Please Note that as @BogdanSahlean has noted this solution will work for newly created objects but not for existing tables and columns. 请注意,由于@BogdanSahlean已经注意到此解决方案适用于新创建的对象,但不适用于现有的表和列。
From MSDN: 来自MSDN:

You can change the collation of any new objects that are created in a user database by using the COLLATE clause of the ALTER DATABASE statement. 您可以使用ALTER DATABASE语句的COLLATE子句更改在用户数据库中创建的任何新对象的排序规则。 This statement does not change the collation of the columns in any existing user-defined tables. 此语句不会更改任何现有用户定义表中列的排序规则。 These can be changed by using the COLLATE clause of ALTER TABLE. 可以使用ALTER TABLE的COLLATE子句更改这些内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM