我是一个自学成才、能力模糊的 SQL 用户。对于我正在写的一个观点,我正在尝试开发一个“条件LEFT
”字符串拆分命令(大概稍后会被一个“条件RIGHT
”加入 - 其中:
- 如果一个字符串(我们称之为'haystack')包含一个特定的模式(我们称之为'needle'),它将被修剪到该模式的左侧
- 否则,整个字符串将原封不动地传递。
所以,如果我们的模式是' - ',
- 'A long string - contains the pattern' 将输出为 'A long string'
- “没有模式的字符串”将按原样返回。
我没有使用最粗暴的方法来做到这一点,而是试图提出一种避免重复任何子句(例如 if 0 < CHARINDEX
,然后 take CHARINDEX
- 1 等)的方法,而是利用条件NULL
ing。
然而——这就是我尝试创造性所得到的——我遇到了一个看似非常基本的绊脚石。请注意下面的代码和结果,让我知道你是否可以复制它 - 因此它是一个错误还是我错过了一些特殊的东西。我已经在 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'?
是否有某种隐含CAST
的 to varchar(1)
?故意cast
不做varchar(max)
任何改变。这里还能发生什么?
我只是在做一些非常愚蠢的事情吗?因为从这里,我无法弄清楚我做错了什么,所以它看起来真的像一个错误。我希望 2014 年的测试能够证明它是旧 2008 R2 中的一个错误,但是,唉,它们的行为相同(或者更确切地说,不一样)。
在此先感谢您,希望能将我从可能是一个令人困惑的生存危机之夜中解救出来。