SQL大小写敏感字符串比较

315

如何比较字符串,使得仅当每个字符串的大小写相同时比较才为真。例如:

Select * from a_table where attribute = 'k'

将返回一个带有属性'K'的行。我不想要这种行为。


2
这可能不是你所需要的,但你可以更改排序规则或在查询中使用特定的排序规则。 - Kane
10
哪种SQL产品? - onedaywhen
6个回答

509
Select * from a_table where attribute = 'k' COLLATE Latin1_General_CS_AS 

事情成了。


8
我通常会使用Latin1_General_Bin。 - gbn
3
标准做法是使用不区分大小写的排序规则,尽管这些排序规则本身是供应商特定的。你使用的是SQL Server语法吗? - onedaywhen
2
在我的情况下,我在我的数据库中有一个区分大小写的列。我需要将其与标准(CI)列进行比较。我使用了以下变体:WHERE Foo.Bar = (Baz.Bar COLLATE Latin1_General_CS_AS) - Hypnovirus
3
谢谢,但是 Latin1_General_CS_AS 是什么?它是特殊关键字吗? - Vijay Singh Rana
3
Latin1_General_CS_AS是排序规则的一种规范。排序规则是一组规则,用于确定数据如何排序和比较。有关更多信息,请参见此页面:http://www.databasejournal.com/features/mssql/article.php/3302341/SQL-Server-and-Collation.htm。 - amccormack
显示剩余5条评论

61
你还可以使用以下语法将该属性转换为区分大小写
ALTER TABLE Table1
ALTER COLUMN Column1 VARCHAR(200)
COLLATE SQL_Latin1_General_CP1_CS_AS

现在您的搜索将是区分大小写的。

如果您想再次使该列 不区分大小写,那么请使用

ALTER TABLE Table1
ALTER COLUMN Column1 VARCHAR(200)
COLLATE SQL_Latin1_General_CP1_CI_AS

我有一个nvarchar类型的列。上面的查询对我没有起作用。有什么原因吗? - sandeep.gosavi

31

您可以轻松地将列转换为VARBINARY(最大长度),长度必须是您预期的最大值,以避免比较缺陷,只需将长度设置为列长度即可。Trim列可以帮助您比较除空格以外的实际值,在您的表列中具有意义和价值。这是一个简单的示例,您可以看到我先Trim列的值,然后进行转换和比较。

CONVERT(VARBINARY(250),LTRIM(RTRIM(Column1))) = CONVERT(VARBINARY(250),LTRIM(RTRIM(Column2)))
希望这可以帮到你。

23

另一种选择是使用HASHBYTES,类似于这样:

SELECT * 
FROM a_table 
WHERE HASHBYTES('sha1', attribute) = HASHBYTES('sha1', 'k')

3
碰撞怎么办?虽然很少见,但我认为可能会有多个字符串哈希到相同的值。 - David Klempfner
是可能的,但在这样一个简单的字符串示例中非常罕见,我认为。 - Dave Sexton
3
@DavidKlempfner 为什么不先进行比较,如果它们匹配,然后再检查 hashbytes?我们可以将其制作成一个函数,并像这样调用它 StringsAreCaseSensitiveEqual(a, b) => a = b AND HASHBYTES('sha1', a) = HASHBYTES('sha1', b) - Demetris Leptos

11

简化通用答案:

SQL区分大小写的字符串比较

以下示例可能会有所帮助:

Declare @S1 varchar(20) = 'SQL'
Declare @S2 varchar(20) = 'sql'

  
if @S1 = @S2 print 'equal!' else print 'NOT equal!' -- equal (default non-case sensitivity for SQL

if cast(@S1 as binary) = cast(Upper(@S2) as binary) print 'equal!' else print 'NOT equal!' -- equal

if cast(@S1 as binary) = cast(@S2 as binary) print 'equal!' else print 'NOT equal!' -- not equal

if  @S1 COLLATE Latin1_General_CS_AS  = Upper(@S2) COLLATE Latin1_General_CS_AS  print 'equal!' else print 'NOT equal!' -- equal

if  @S1 COLLATE Latin1_General_CS_AS  = @S2 COLLATE Latin1_General_CS_AS  print 'equal!' else print 'NOT equal!' -- not equal

 

相比于像运行时计算hashbytes这样的方法,转换可能更有效率,我期望排序规则甚至更快。


3

您可以将属性定义为BINARY,或使用INSTRSTRCMP来执行搜索。


这个回复似乎与问题标签中的SQL Server无关。该数据库管理系统缺少这些INSTRSTRCMP函数。 - Jonas

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