SQL Server : ISNULL(compound NULL condition, 'a string' ) 在某些情况下仅返回第一个字符

标签 sql sql-server string isnull nullif

我是一个自学成才的 SQL 用户。对于我正在写的观点,我正在尝试开发一个'条件LEFT ' 字符串分割命令(可能稍后会被 'conditional RIGHT 加入' - 借此:

  • 如果一个字符串(我们称之为 'haystack')包含特定的模式(我们称之为 'needle'),它将被修剪到该模式的左侧
  • 否则,整个字符串将原封不动地传递。

所以,如果我们的模式是' - ',

  • 'A long string - contains the pattern'将输出为'A long string'
  • “没有模式的字符串”将按原样返回。

我试图想出一种避免重复任何子句的方法,而不是使用最粗暴的方法(例如 if 0 < CHARINDEX ,然后取 CHARINDEX - 1 等)和而是利用条件 NULL

然而——这就是我尝试创造的结果——我遇到了一个看似非常基本的绊脚石。请注意下面的代码和结果,让我知道你是否可以复制它 - 因此它是一个错误还是我错过了一些特殊的东西。我已经在 SQL Server 2008 R2 和 2014(两个 Express 版本)上对此进行了测试。

select
    -- ISNULL: returns 'a big old string'
    ISNULL(null, 'a big old string'),

    -- NULLIF: returns NULL
    left(
        'a big old string',
        nullif
        (
            CHARINDEX
            (
                'needle',
                'haystack'
            ), 0
        ) - 1
    ),

    -- combined: returns just 'a' (1st character of ISNULL condition)
    ISNULL(
        left
        (
            'a big old string', -- the input string. In reality, this would be a column alias, etc.
            nullif
            (
                CHARINDEX       -- Search for the splitting pattern
                (
                    'needle',
                    'haystack'
                ), 0            -- If it's not found, return NULL instead of the usual 0
            ) - 1               -- so that this subtraction produces a NULL, not an invalid negative index
        ),
        'a big old string'      -- If the pattern was not found, we should return the input unaltered
    );

/*
---------------- ---- ----
a big old string NULL a

(1 row(s) affected)
*/

为什么这 2 个子句在孤立的情况下按预期工作,但是 当我将它们组合在一起时,而不是得到它们的效果的总和,我只得到 ISNULL 的第一个字符字符串 - 'a'?

是否有某种隐含的CASTvarchar(1) ?故意cast转至 varchar(max)没有任何区别。这里还能发生什么?

我只是在做一些非常愚蠢的事情吗?因为从这里,我无法弄清楚我做错了什么,所以它看起来真的像一个错误。我希望 2014 年的测试能证明它是旧 2008 R2 中的一个错误,但可惜,它们的行为相同(或者,更确切地说,不一样)。

在此先感谢您,希望能将我从可能是一个令人困惑的生存危机之夜中解救出来。

最佳答案

这是 isnullcoalesce 之间的区别——因为 isnull 的第一个参数是 char(1),这将是返回值的类型陈述。使用合并,您将获得正确的结果。

Isnull :

返回与 check_expression 相同的类型。如果提供文字 NULL 作为 check_expression,则返回 replacement_value 的数据类型。如果提供了一个文字 NULL 作为 check_expression 并且没有提供 replacement_value,则返回一个 int。

Coalesce :

返回具有最高数据类型优先级的表达式的数据类型。如果所有表达式都不可为空,则结果类型为不可空。

关于SQL Server : ISNULL(compound NULL condition, 'a string' ) 在某些情况下仅返回第一个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31388813/

相关文章:

sql-server - 使故障转移组中的 Azure SQL 数据库脱机

java - 阿拉伯文本在 web 应用程序中显示,无需更改数据库

c++ 何时返回 const char* 而不是 std :string

c++ - `re.sub(pattern, functor, string)` 对于 C++

SQL 处理顺序

sql - 尝试对 SQL Server 中的两列求和导致错误消息

SQL - 查询报告 MAX DATE 结果或 NULL 结果

java - Spring hibernate : Could not extract result set metadata

sql - SQL Server 中的负 SPID?

string - KMP 前缀表直觉