运行 服务器 2019 上的意外订单 运行 OR 运算符

Unexpected order running OR operator on SQL Server 2019

我在从 SQL Server 2008 R2 迁移到 SQL Server 2019 时遇到问题。 我的代码

DECLARE @str NVARCHAR(50) = 'all',
        @int TINYINT = 1

DECLARE @tmp TABLE (val nvarchar(MAX))
INSERT INTO @tmp VALUES('123')
INSERT INTO @tmp VALUES('all')

SELECT val
FROM @tmp
WHERE @str = 'ALL' OR @int = val

使用SQL Server 2008 R2 时,没问题。如下所示的预期输出

val
123
all

但是,当我迁移到SQL Server 2019 时,出现如下错误。再说了,这在2019年也是不寻常的。

Msg 245 Level 16 State 1 Line 8 Conversion failed when converting the nvarchar value 'all' to data type int.

如您所见,第二种情况 OR @int = val 意外发生。

我想知道它是否由于与 OR 运算符case sensitive[= 的顺序相关的任何重大更改而失败39=] ALL vs all 在下一个 SQL Server 2008 R2 版本中。


已更新

抱歉,我的重现代码让你们感到困惑。 This is my original code

你应该做这三件事中的两件事:

(

  1. 要么使用DECLARE @int nvarchar(max) = 1

  2. 使用WHERE val = CONVERT(nvarchar(max), @int)

)

  1. 更改为使用 STRING_SPLIT。即使在本机解决方案存在之前,循环函数也是您可以用来拆分字符串的效率最低的方法之一。参见 https://sqlblog.org/split

这个db<>fiddlefiddle演示。

this one 说明了为什么 WHERE @str = 'ALL' OR (@str <> 'ALL' AND @int = val) 不是解决方案。您选择的这些模式仅在 @str 总是 'all' 时才有效,因为它们在其他任何情况下都会中断。那么为什么要有 OR 呢?


您一直坚持 SQL 服务器应该服从从左到右的评估,但我们一直告诉您事实并非如此。

这里是 an article by Bart Duncan at Microsoft,他在 SQL 服务器上工作,在发表更多评论或进一步编辑您的问题之前,您绝对应该完整阅读。不过,关键点是:

You cannot depend on expression evaluation order for things like

WHERE <expr1> OR <expr2>

since the optimizer might choose a plan that evaluates the second predicate before the first one.