从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 sensitive
ALL
与all
的顺序相关的任何中断更改而失败的。
更新
很抱歉我的复制代码让你们混淆了。这是我的原始代码
您应该做这三件事中的两件:
(
-
使用
DECLARE @int nvarchar(max) = 1
或
-
使用
WHERE val = CONVERT(nvarchar(max), @int)
(
和
- 更改为使用
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>
这样的事情,您不能依赖于表达式求值顺序,因为优化器可能会选择在第一个谓词之前求值第二个谓词的计划。