SQL服务器在where表达式中忽略大小写

Rau*_*ait 81 sql sql-server case-insensitive where-clause

如何构造SQL查询(MS SQL Server),其中"where"子句不区分大小写?

SELECT * FROM myTable WHERE myField = 'sOmeVal'
Run Code Online (Sandbox Code Playgroud)

我希望结果无视案例回来

Ada*_*son 127

在SQL Server数据库的默认配置,字符串比较不区分大小写.如果您的数据库覆盖此设置(通过使用备用排序规则),则您需要指定要在查询中使用的排序规则类型.

SELECT * FROM myTable WHERE myField = 'sOmeVal' COLLATE SQL_Latin1_General_CP1_CI_AS
Run Code Online (Sandbox Code Playgroud)

请注意,我提供的排序规则只是一个例子(虽然它很可能对你来说很好).可以在此处找到有关SQL Server排序规则的更全面的概述.


And*_*ovs 28

通常,字符串比较不区分大小写.如果您的数据库配置为区分大小写的排序规则,则需要强制使用不区分大小写的排序规则:

SELECT balance FROM people WHERE email = 'billg@microsoft.com'
  COLLATE SQL_Latin1_General_CP1_CI_AS 
Run Code Online (Sandbox Code Playgroud)

  • 看起来有人比我快:-) (4认同)
  • +1我更喜欢你的简短(和无滚动条)答案. (4认同)

Dan*_*nny 21

我在其他地方找到了其他解 就是说,要用

upper(@yourString)
Run Code Online (Sandbox Code Playgroud)

但是这里的每个人都说,在SQL Server中,它并不重要,因为它无论如何都忽略了案例?我很确定我们的数据库区分大小写.

  • 你是正确的,数据库可以区分大小写,但这是非常低效的,即使它是需要的.COLLATE是要使用的关键字. (5认同)
  • 也被投票赞成.我可以想到很多有用的案例.此外,通常有多种好方法可以做某事. (2认同)

Sol*_*zky 9

前2个答案(来自Adam RobinsonAndrejs 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,French vs. Hebrew等)控制。请参阅下面的第9点。

其他四个答案在不同程度上都是错误的。

我将在这里澄清所有误解,以便读者希望做出最适当/最有效的选择。

  1. 不要使用UPPER()。那完全是不必要的额外工作。使用COLLATE子句。在任何一种情况下都需要进行字符串比较,但是UPPER()还必须逐个字符地进行检查,以查看是否存在大写映射,然后进行更改。而且您需要在两侧都这样做。添加COLLATE仅指示处理使用与默认情况下不同的规则集来生成排序关键字。正如在此测试脚本(在PasteBin上)证明的COLLATE那样,使用绝对比使用更有效(或者,如果您喜欢这个词,则为“性能” UPPER()

    @Ceisc在@Danny的答案中提到了一个问题:

    在某些语言中,转换不是往返的。即LOWER(x)!= LOWER(UPPER(x))。

    土耳其语大写字母“?” 是常见的例子。

  2. 不,排序规则不是数据库范围的设置,至少在这种情况下不是这样。有一个数据库级别的默认排序规则,它用作未指定COLLATE子句的更改列和新创建列的默认排序规则(很可能是这种常见误解的来源),但除非您是将字符串文字和变量与其他字符串文字和变量进行比较,或者您正在引用数据库级元数据。

  3. 不,不是按查询排序。

  4. 排序规则是基于谓词(即,某些操作数)或表达式,而不是针对每个查询。对于整个查询,不仅是WHERE子句,都是如此。这包括JOIN,GROUP BY,ORDER BY,PARTITION BY等。

  5. 不,由于以下原因,请不要转换为VARBINARY(例如convert(varbinary, myField) = convert(varbinary, 'sOmeVal')):

    1. 这是一个二进制比较,不区分大小写(这是这个问题的要求)
    2. 如果您确实想要二进制比较,请使用二进制排序规则。使用一个与结束_BIN2,如果你使用的是SQL Server 2008或更新,否则你没有选择,只能使用一个结束与_BIN。如果数据是正确的,NVARCHAR那么使用哪种语言环境都没关系,因为在这种情况下它们都是相同的,因此Latin1_General_100_BIN2始终有效。如果数据是VARCHAR,你必须使用相同的语言环境中的数据是目前在(如Latin1_GeneralFrenchJapanese_XJIS,等),因为语言环境决定了所使用的代码页,并改变代码页可以改变的数据(即数据丢失)。
    3. 在不指定大小的情况下使用可变长度数据类型将取决于默认大小,根据使用数据类型的上下文,存在两种不同的默认值。字符串类型为1或30。与CONVERT()它一起使用时将使用30的默认值。危险是,如果字符串可以超过30个字节,它将被静默截断,并且您很可能会从该谓词中获得错误的结果。
    4. 即使您想要区分大小写的比较,二进制排序规则也不区分大小写(另一个非常常见的误解)。
  6. 不,LIKE并不总是区分大小写。它使用被引用列的排序规则,或将变量与字符串文字进行比较时使用的数据库排序规则,或通过可选COLLATE子句指定的排序规则。

  7. LCASE不是SQL Server函数。它似乎是Oracle或MySQL。还是Visual Basic?

  8. 由于问题的上下文是将列与字符串文字进行比较,因此实例的排序规则(通常称为“服务器”)或数据库的排序规则都不会对此处产生任何直接影响。排序规则存储在每一列中,每一列可以具有不同的排序规则,这些排序规则不必与数据库的默认排序规则或实例的排序规则相同。当然,如果COLLATE在创建数据库时未指定子句,则实例排序规则是新创建的数据库将用作默认排序规则的默认排序规则。同样,如果COLLATE未指定该子句,则数据库的默认排序规则将是更改后的列或新创建的列将使用的排序规则。

  9. 您应该使用不区分大小写的排序规则,否则该排序规则与列的排序规则相同。使用以下查询查找列的排序规则(更改表的名称和架构名称):

    SELECT col.*
    FROM   sys.columns col
    WHERE  col.[object_id] = OBJECT_ID(N'dbo.TableName')
    AND    col.[collation_name] IS NOT NULL;
    
    Run Code Online (Sandbox Code Playgroud)

    然后只需将更_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[_]%';
    
    Run Code Online (Sandbox Code Playgroud)

    例如,假设该列正在使用Japanese_XJIS_100_BIN2,请执行以下操作:

    SELECT *
    FROM   sys.fn_helpcollations() col
    WHERE  col.[name] LIKE N'Japanese_XJIS_100[_]CI[_]%';
    
    Run Code Online (Sandbox Code Playgroud)

有关归类,编码等的更多信息,请访问:归类信息


小智 7

不,只有使用LIKE不起作用.LIKE搜索与您给定模式完全匹配的值.在这种情况下,LIKE只会找到文本'sOmeVal'而不是'someval'.

一个可用的解决方案是使用该LCASE()功能.LCASE('sOmeVal')获取文本的小写字符串:'someval'.如果您在比较的两侧使用此功能,它的工作原理如下:

SELECT * FROM myTable WHERE LCASE(myField) LIKE LCASE('sOmeVal')

该语句比较了两个小写字符串,因此你的'sOmeVal'将匹配'someval'的所有其他符号(例如'Someval','sOMEVAl'等).

  • 在整理了_CI的99.9%的SQL Server安装中,LIKE是Case Insensitive. (7认同)