SQL Server 忽略 where 表达式中的大小写
-
11-07-2019 - |
题
如何构造“where”子句不区分大小写的 SQL 查询 (MS SQL Server)?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
我希望结果返回时忽略此情况
解决方案
在SQL Server数据库的默认配置,字符串比较的是强>不区分大小写的。如果你的数据库覆盖此设置(通过使用替代归类的),那么你就需要指定要在查询中使用什么样的整理。
SELECT * FROM myTable WHERE myField = 'sOmeVal' COLLATE SQL_Latin1_General_CP1_CI_AS
请注意,我所提供的整理只是一个例子(尽管它更比可能将功能就好了你)。 SQL Server排序规则的更彻底的轮廓可以在这里找到 。
其他提示
通常,字符串比较是不区分大小写。如果您的数据库配置为区分大小写排序,您需要强制使用不区分大小写的一个:
SELECT balance FROM people WHERE email = 'billg@microsoft.com'
COLLATE SQL_Latin1_General_CP1_CI_AS
我发现了另一个解决方案在别处;也就是说,使用
upper(@yourString)
但每个人都在这里是说,在SQL Server中,这并不重要,因为它无论如何忽略大小写?我敢肯定我们的数据库是区分大小写的。
没有,只能用LIKE
将无法正常工作。 LIKE
搜索完全匹配您给定的模式值。在这种情况下LIKE
会发现只有文本“sOmeVal”而不是“someval”。
一个pracitcable溶液是使用LCASE()
功能。 LCASE('sOmeVal')
得到您的文本字符串小写:“someval”。如果您使用此功能,您两侧对比,它的工作原理:
SELECT * FROM myTable WHERE LCASE(myField) LIKE LCASE('sOmeVal')
在语句比较两个小写字符串,所以你“sOmeVal”将“someval”的每个其它符号相匹配(例如,“Someval”,“sOMEVAl”等)。
前 2 个答案(来自 亚当·罗宾逊 和 安德烈斯·凯尼科夫斯)有点正确,因为它们在技术上确实有效,但它们的解释是错误的,因此在许多情况下可能会产生误导。例如,虽然 SQL_Latin1_General_CP1_CI_AS
排序规则在许多情况下都有效,但不应假定它是适当的不区分大小写的排序规则。事实上,考虑到 O.P.在使用区分大小写(或可能是二进制)排序规则的数据库中工作,我们知道 O.P.没有使用许多安装的默认排序规则(尤其是在使用美国英语作为语言的操作系统上安装的任何安装): SQL_Latin1_General_CP1_CI_AS
. 。当然,O.P. 可以 正在使用 SQL_Latin1_General_CP1_CS_AS
, ,但是当与 VARCHAR
数据,重要的是不要更改代码页,因为它可能导致数据丢失,并且这是由排序规则的区域设置/区域性控制的(即。Latin1_General vs 法语 vs 希伯来语等)。请参阅下面第 9 点。
其他四个答案都不同程度地错误。
我将在这里澄清所有的误解,以便读者能够做出最合适/最有效的选择。
不使用
UPPER()
. 。这完全是不必要的额外工作。用一个COLLATE
条款。在任何一种情况下都需要进行字符串比较,但是使用UPPER()
还必须逐个字符地检查是否存在大写映射,然后更改它。你需要在两侧都这样做。添加COLLATE
只是指示处理使用与默认情况下不同的规则集来生成排序键。使用COLLATE
绝对比使用更有效(或“高性能”,如果你喜欢这个词:)UPPER()
, ,如此证明 测试脚本(在 PasteBin 上).还有这样的问题 @Ceisc 在 @Danny 的回答中指出:
在某些语言中,大小写转换不会往返。IE。下(x)!=下(上(x))。
土耳其语大写“ı”是常见的例子。
不,排序规则不是数据库范围的设置,至少在这种情况下不是。有一个数据库级别的默认排序规则,它用作更改的和新创建的未指定列的默认排序规则
COLLATE
子句(这可能是这种常见误解的来源),但它不会直接影响查询,除非您将字符串文字和变量与其他字符串文字和变量进行比较,或者引用数据库级元数据。不,排序规则不是针对每个查询的。
排序规则是 每个谓词 (IE。某些操作数某些)或表达式,而不是每个查询。这对于整个查询都是如此,而不仅仅是
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
, 等),因为区域设置决定了所使用的代码页,并且更改代码页可以更改数据(即数据丢失)。 - 使用可变长度数据类型而不指定大小将依赖于默认大小,并且根据使用数据类型的上下文,有两种不同的默认值。对于字符串类型,它是 1 或 30。当与
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[_]%';
有关排序规则、编码等的更多信息,请访问: 校对信息
可以强制区分大小写,浇铸到那样的VARBINARY:
SELECT * FROM myTable
WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
什么数据库,是你吗?随着MS SQL Server中,这是一个数据库范围的设置,或与COLLATE关键字,你可以过骑它每查询。