【问题标题】:Case-sensitive variable / string literal comparison in Stored Procedure存储过程中区分大小写的变量/字符串文字比较
【发布时间】:2014-05-11 23:11:30
【问题描述】:

我需要在 SQL Server 2008 的存储过程中进行区分大小写的比较,但不知道如何实现。

我已经尝试了以下代码:

Declare @andJob  varchar(1)

select @andJob = (SELECT szUserdefined6 from inserted ) 

if  @andJob like 'y%'
begin
  /* Do Stuff */
end

【问题讨论】:

  • 在网上搜索collation sequences:字符串(CHAR、VARCHAR 等)使用不同的排序规则存储,默认使用的是 SQL Server 中的设置。一些排序规则是区分大小写的,有些是不区分大小写的。您有一个使用区分大小写序列的服务器。要么更改服务器设置,要么手动定义要在该表中的该字段上使用的排序规则。但要小心混合/比较不同的序列,因为它需要将一个翻译成另一个。
  • 我已将该字段设置为 Latin1_General_CS_AI,这对查询没有影响。
  • 也尝试显式强制对'y%' 进行排序。使用执行计划检查是否正在发生任何对话。
  • @MatBailie 关于您在这里的第一条评论,此操作与服务器/实例级排序规则无关。该级别控制变量名称,但不控制它们的值。影响变量值的是数据库级别的排序规则。另外,请在下面查看我的answer可能正是您在上面的评论中建议的,但并不完全确定。
  • 嗨@joebohen。我只是想知道您是否有机会查看我的answer。我刚刚更新了它以包含一个简单的示例,如果您不再有相同的环境可供您使用,可以复制和粘贴该示例以查看它是如何工作的(我确实意识到距离您发布这个问题已经快 5 年了; -)。

标签: sql-server sql-server-2008 tsql collation case-sensitive


【解决方案1】:

您可以使用 COLLATION 选项来实现此目的。如Link 进一步可以在MSDN 找到排序选项列表。

【讨论】:

    【解决方案2】:

    很可能,声明一个排序规则就可以了。看这两个问题可以找到详细解释:

    SQL Case Sensitive String Compare

    SQL server ignore case in a where expression

    这些答案之一能解决您的问题吗?

    【讨论】:

      【解决方案3】:

      问题只是字符串文字/常量和变量(包括参数)使用当前数据库的默认排序规则。使用列时,将使用列的排序规则。在这里,您将列中的值存储到变量中,因此列的排序规则不再重要。

      由于您显然处于具有不区分大小写的默认排序规则的数据库中,因此您需要指定 COLLATE 关键字作为比较的一部分。含义:

      IF ( @andJob LIKE 'y%' COLLATE Latin1_General_CS_AI )
      

      这将覆盖使用数据库排序规则进行比较的默认行为。

      例如:

      IF (DB_ID(N'CaseInsensitive') IS NULL)
      BEGIN
        CREATE DATABASE [CaseInsensitive] COLLATE Latin1_General_100_CI_AS;
        ALTER DATABASE [CaseInsensitive] SET RECOVERY SIMPLE;
      END;
      GO
      
      USE [CaseInsensitive];
      
      SELECT 1 WHERE 'YES' LIKE 'y%';
      -- 1
      
      SELECT 2 WHERE 'YES' LIKE 'y%' COLLATE Latin1_General_100_CS_AS;
      -- (nothing)
      
      
      /* -- Clean up:
      USE [master];
      DROP DATABASE [CaseInsensitive];
      */
      

      另外,您将变量声明为varchar(1),这似乎有点小。它会将szUserdefined6 中的任何值截断为第一个字符,我不确定这是预期的行为。

      另外,在触发器中执行select @andJob = (SELECT szUserdefined6 from inserted ) 时需要非常小心。从多行 DML 操作执行的触发器将在 inserted 和/或 deleted 表中每个受影响的行有一行。您在此处所做的仅捕获 inserted 表中最后一行的值,因此只有在 NEVER 多行 INSERTUPDATE 反对此表时它才真正起作用.

      有关排序规则、编码等的更多信息,请访问:Collations Info

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        • 2015-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-27
        相关资源
        最近更新 更多