在“ where”子句不区分大小写的情况下,如何构造SQL查询(MS SQL Server)?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
我希望结果不考虑情况而返回
在“ where”子句不区分大小写的情况下,如何构造SQL查询(MS SQL Server)?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
我希望结果不考虑情况而返回
Answers:
在SQL Server数据库的默认配置,字符串比较是不区分大小写。如果您的数据库覆盖了此设置(通过使用替代排序规则),则需要指定在查询中使用哪种排序规则。
SELECT * FROM myTable WHERE myField = 'sOmeVal' COLLATE SQL_Latin1_General_CP1_CI_AS
请注意,我提供的排序规则只是一个示例(尽管很可能对您来说很好用)。有关SQL Server排序规则的更详尽概述,请参见此处。
UPPER
或LOWER
大小写,然后使用LIKE
进行搜索?
通常,字符串比较不区分大小写。如果您的数据库配置为区分大小写排序规则,则需要强制使用不区分大小写的排序规则:
SELECT balance FROM people WHERE email = 'billg@microsoft.com'
COLLATE SQL_Latin1_General_CP1_CI_AS
我在其他地方找到了另一个解决方案。即使用
upper(@yourString)
但是这里的每个人都在说,在SQL Server中,这没关系,因为它还是忽略大小写吗?我很确定我们的数据库区分大小写。
前2个答案(来自Adam Robinson和Andrejs Cainikovs)在某种程度上说是正确的,因为它们在技术上确实有效,但是它们的解释是错误的,因此在许多情况下可能会引起误解。例如,尽管SQL_Latin1_General_CP1_CI_AS
排序规则在许多情况下都可以使用,但不应认为它是适当的不区分大小写的排序规则。实际上,考虑到OP正在使用区分大小写(或可能是二进制)的排序规则在数据库中工作,我们知道OP没有使用许多安装(默认情况下,尤其是操作系统上安装的默认排序规则)的排序规则使用美国英语作为语言)SQL_Latin1_General_CP1_CI_AS
。当然,OP可能正在使用SQL_Latin1_General_CP1_CS_AS
,但是当与VARCHAR
数据,重要的是不要更改代码页,因为这可能会导致数据丢失,并且这受排序规则的区域设置/区域性(即Latin1_General,法语,希伯来语等)控制。请参阅下面的第9点。
其他四个答案在不同程度上都是错误的。
我将在这里澄清所有误解,以便读者希望做出最适当/最有效的选择。
不要使用UPPER()
。那完全是不必要的额外工作。使用COLLATE
子句。在任何一种情况下都需要进行字符串比较,但是UPPER()
还必须逐个字符地进行检查,以查看是否存在大写映射,然后进行更改。而且您需要在两侧都这样做。添加COLLATE
仅指示处理使用与默认情况下不同的规则集来生成排序关键字。正如在此测试脚本(在PasteBin上)证明的COLLATE
那样,使用绝对比使用更有效(或者,如果您喜欢这个词,则为“性能” )。UPPER()
在某些语言中,转换不是往返的。即LOWER(x)!= LOWER(UPPER(x))。
土耳其语大写“İ”是常见的示例。
不,排序规则不是数据库范围的设置,至少在这种情况下不是这样。有一个数据库级别的默认排序规则,它用作未指定COLLATE
子句的更改列和新创建的列的默认排序规则(很可能是这种常见的误解的来源),但是除非您这样做,否则它不会直接影响查询。将字符串文字和变量与其他字符串文字和变量进行比较,或者您正在引用数据库级元数据。
不,不是按查询排序。
排序规则是基于谓词(即,某些操作数)或表达式,而不是针对每个查询。对于整个查询,不仅是WHERE
子句,都是如此。这包括JOIN,GROUP BY,ORDER BY,PARTITION BY等。
不,由于以下原因,请不要转换为VARBINARY
(例如convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
):
_BIN2
,如果你使用的是SQL Server 2008或更新,否则你没有选择,只能使用一个结束与_BIN
。如果数据是正确的,NVARCHAR
那么使用哪种语言环境都没有关系,因为在这种情况下它们都是相同的,因此Latin1_General_100_BIN2
始终有效。如果数据是VARCHAR
,你必须使用相同的语言环境中的数据是目前在(如Latin1_General
,French
,Japanese_XJIS
,等),因为语言环境决定了所使用的代码页,并改变代码页可以改变的数据(即数据丢失)。CONVERT()
它一起使用时将使用30个默认值。危险是,如果字符串可以超过30个字节,它将被静默截断,并且您很可能会从该谓词中获得错误的结果。不,LIKE
并不总是区分大小写的。它使用被引用列的排序规则,或将变量与字符串文字进行比较时使用的数据库排序规则,或通过可选COLLATE
子句指定的排序规则。
LCASE
不是SQL Server函数。它似乎是Oracle或MySQL。还是Visual Basic?
由于问题的上下文是将列与字符串文字进行比较,因此实例的排序规则(通常称为“服务器”)或数据库的排序规则都不会对此处产生任何直接影响。排序规则存储在每一列中,并且每一列可以具有不同的排序规则,并且这些排序规则不必与数据库的默认排序规则或实例的排序规则相同。当然,如果COLLATE
在创建数据库时未指定子句,则实例排序规则是新创建的数据库将用作默认排序规则的默认排序规则。同样,如果COLLATE
未指定子句,则数据库的默认排序规则将是更改后的列或新创建的列将使用的列。
您应使用不区分大小写的排序规则,否则该排序规则与列的排序规则相同。使用以下查询查找列的排序规则(更改表的名称和架构名称):
SELECT col.*
FROM sys.columns col
WHERE col.[object_id] = OBJECT_ID(N'dbo.TableName')
AND col.[collation_name] IS NOT NULL;
然后只需将更_CS
改为即可_CI
。所以,Latin1_General_100_CS_AS
将变为Latin1_General_100_CI_AS
。
如果该列使用二进制排序规则(以_BIN
或结尾_BIN2
),则使用以下查询查找类似的排序规则:
SELECT *
FROM sys.fn_helpcollations() col
WHERE col.[name] LIKE N'{CurrentCollationMinus"_BIN"}[_]CI[_]%';
例如,假设该列正在使用Japanese_XJIS_100_BIN2
,请执行以下操作:
SELECT *
FROM sys.fn_helpcollations() col
WHERE col.[name] LIKE N'Japanese_XJIS_100[_]CI[_]%';
有关归类,编码等的更多信息,请访问:归类信息
不,仅使用LIKE
不起作用。LIKE
搜索与您的给定模式完全匹配的值。在这种情况下,LIKE
只会找到文本“ sOmeVal”,而不是“ someval”。
一个可行的解决方案是使用该LCASE()
功能。LCASE('sOmeVal')
获取文本的小写字符串:“ someval”。如果在比较的两面都使用此功能,则可以使用:
SELECT * FROM myTable WHERE LCASE(myField) LIKE LCASE('sOmeVal')
该语句比较两个小写字符串,以便您的“ sOmeVal”将与“ someval”的所有其他符号匹配(例如,“ Someval”,“ sOMEVAl”等)。
您可以强制区分大小写,将其强制转换为这样的varbinary:
SELECT * FROM myTable
WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
WHERE
语句的末尾添加一次,这会影响所有WHERE
子句,对吗?