Sql server SQL';s选择是选择错误的结果(并产生“严重”错误)
有趣的是,我总是可以通过以下方式触发“严重”错误:Sql server SQL';s选择是选择错误的结果(并产生“严重”错误),sql-server,tsql,Sql Server,Tsql,有趣的是,我总是可以通过以下方式触发“严重”错误: WITH SillySequence (Ordinal) AS ( SELECT 1 UNION ALL SELECT (1 + Ordinal) FROM SillySequence WHERE Ordinal < 100 ) SELECT SometimesNull = CHOOSE( 5 + ABS(CHECKSUM(NEWID()) % 2),
WITH SillySequence (Ordinal) AS (
SELECT 1
UNION ALL
SELECT (1 + Ordinal) FROM SillySequence WHERE Ordinal < 100
)
SELECT
SometimesNull =
CHOOSE(
5 + ABS(CHECKSUM(NEWID()) % 2),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
FROM SillySequence
消息0,11级,状态0,第20行
无法继续执行,因为会话处于终止状态
消息0,级别20,状态0,第20行
当前命令发生严重错误。如果有结果,则应放弃
我已经在SQL Server 2016中使用兼容性级别
110
、120
和130
测试了上述示例。您误解了choose()
的工作原理。在我看来,这是因为你是一个聪明的人,期望软件以合理的方式工作
choose(x,a,b)
的定义相当于:
SELECT CHOOSE(
(SELECT 1 + ABS(CHECKSUM(NEWID()) % 2)),
'one', 'two')
当x
是一个常数时,这就足够简单了。当x
引用一列时(如您的“永不为空”示例中所示),就足够简单了。当x
是非易失性表达式时,就足够简单了。当x
是一个不确定的表达式时,99.9%是违反直觉的(有些人可能会有不同的想法和评论;)
这是什么意思?好吧,你正在执行:
(case when x = 1 then a
when x = 2 then b
end)
也就是说,表达式有两个随机数。事实上,每个可能的目标都有一个随机数(我说的是“反直觉”,不是吗?)
好吧,大约25%的时候,两种比较都会失败。并且,结果将是
NULL
。我记得我第一次学习时花了很多时间调试代码。NEWID()计算了10次。案例和选择在这里是相似的;请看。如果我没记错的话,COALESCE()
会遇到类似的问题,因为它会被重写为一个大小写
表达式。特别令人困惑,因为ISNULL()
不是那样工作的。谢谢你的回答!“严重错误”仍然是个谜,但这解释了最初的行为(否则无法解释)。
(case when x = 1 then a
when x = 2 then b
end)
(case when 1 + ABS(CHECKSUM(NEWID()) % 2) = 1 then a
when 1 + ABS(CHECKSUM(NEWID()) % 2) = 2 then b
end)