SQL Server 2019上运行OR运算符的意外订单



从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在转换nvarchar值"all"到数据类型int.

如您所见,第二个条件OR @int = val意外发生。

我想知道在下一个SQL Server 2008 R2版本中,它是否是由于与OR运算符case sensitiveALLall的顺序相关的任何中断更改而失败的。


更新

很抱歉我的复制代码让你们混淆了。这是我的原始代码

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

(

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

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

(

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

此数据库<gt;小提琴小提琴示范。

这说明了为什么WHERE @str = 'ALL' OR (@str <> 'ALL' AND @int = val)不是一个解决方案。只有当@str总是'all'时,您选择的这些模式才有效,因为当是其他模式时,它们都会崩溃。那么为什么有OR呢?


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

这是微软的Bart Duncan的一篇文章,他曾在SQL Server上工作,在发表更多评论或进一步编辑问题之前,你绝对应该完整阅读这篇文章。然而,关键点是:

对于

WHERE <expr1> OR <expr2>

这样的事情,您不能依赖于表达式求值顺序,因为优化器可能会选择在第一个谓词之前求值第二个谓词的计划。

最新更新