CASE语句中随机生成的值返回NULL

根据这篇文章,在SQL Server中生成随机值的正确方法是:

ABS(CHECKSUM(NewId())) % 14   -- Returns a value between 0 and 13

但是,在case语句中使用此表达式时,例如:

SELECT
    CASE ABS(CHECKSUM(NEWID())) % 4 
        WHEN 0 THEN 'String A' 
        WHEN 1 THEN 'String B' 
        WHEN 2 THEN 'String C' 
        WHEN 3 THEN 'String D'
    END AS RandomString -- Returns String A, B, C, D and NULLs.
FROM sys.all_objects

如本SQL小提琴所示,outputtet RandomString列包含一些NULL 我发现可以将随机化表达式包装在CTE中,以避免输出中出现NULL,但是我仍然想知道为什么上面的代码返回NULL?

WITH RandomNumber AS (
    SELECT ABS(CHECKSUM(NEWID())) % 4 AS N FROM sys.all_objects
)
SELECT TOP 100
    CASE N
        WHEN 0 THEN 'String A' 
        WHEN 1 THEN 'String B' 
        WHEN 2 THEN 'String C' 
        WHEN 3 THEN 'String D'
    END AS RandomString -- Does not return any NULLs. Only String A, B, C and D.
FROM RandomNumber

我尝试使用略有不同的方法生成随机数,但结果是相同的:

CAST(RAND(CHECKSUM(NEWID())) * 4 AS INT)  -- Returns a value between 0 and 3

这似乎是SQL Server 2014上的问题,我尚未在其他版本上对其进行测试。

Damien_The_Unbeliever

NULL之所以生成s,是因为无法保证特定表达式将被计算多少次。

您想要的是让SQL Server按照以下方式进行操作:

let x = GenerateRandomNumber()
if x = 1 then 'String 1'
if x = 2 then 'String 2'
if x = 3 then 'String 3'
if x = 4 then 'String 4'

(这里GenerateRandomNumber()ABS(CHECKSUM(NEWID())) % 4); 但是SQL Server实际执行的操作是:

if GenerateRandomNumber() = 1 then 'String 1'
if GenerateRandomNumber() = 2 then 'String 2'
if GenerateRandomNumber() = 3 then 'String 3'
if GenerateRandomNumber() = 4 then 'String 4'

因此,只有NULL在碰巧为一个特定的比较操作选择正确的随机数时,您才会获得非结果。

我认为即使使用CTE,也无法保证SQL Server不会生成上面的第二个代码块之类的东西。如果您想要一个稳定的,生成一次的随机数,则需要安排将该值存储在某个位置(例如,在表变量或临时表中)。


我专注于保证的原因是,您不想最终根据当前观察到的行为编写代码。当SQL Server 2008在我们正在使用该TOP 100 PERCENT ... ORDER BY技巧的视图中停止对结果进行“排序”时,报告了很多“问题” –某些情况在2005和更早版本上发生了(大部分)起作用,但不再起作用。

同样,如果有人要求我提供一个返回数字的表达式,那么5我可以向他们提供该表达式,DATEPART(day,GETUTCDATE())并让他们在所需的任意数量的行上运行尽可能多的查询(在接下来的8小时内),但这并不意味着我d推荐它作为解决问题的方法。

而且,我们知道SQL Server在某些方面对评估顺序的决策可能会令人惊讶。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在case语句中返回消息而不是null

来自分类Dev

在case语句中返回布尔值

来自分类Dev

CASE语句中的空值

来自分类Dev

当 case 语句返回 null postgresql 时处理 null 值

来自分类Dev

如何在 SQL Server 2008 中的 Case 语句中返回 Null

来自分类Dev

Snowflake case语句返回错误,而不是ELSE子句中指定的值

来自分类Dev

在返回不同数据类型的CASE语句中转换为CHAR值

来自分类Dev

在CASE语句中返回多个结果时,仅更新一次行值

来自分类Dev

返回结果集的 where 子句中的 case 语句包含空值

来自分类Dev

从executemany语句中获取“返回”值

来自分类Dev

PHP在条件语句中返回cookie的值

来自分类Dev

从executemany语句中获取“返回”值

来自分类Dev

如何在switch语句中使用随机生成的数字?

来自分类Dev

在verilog或系统verilog中在case语句中生成块

来自分类Dev

在Verilog或系统Verilog中在case语句中生成块

来自分类Dev

如何在WHERE子句CASE语句中返回多列

来自分类Dev

PHP:从case语句中返回一个jQuery警报

来自分类Dev

Case语句中的TODATETIMEOFFSET

来自分类Dev

CASE 语句中的 WHERE

来自分类Dev

where 子句中的 case 语句使用 not like 和 is not null

来自分类Dev

在case语句中使用外部ENUM值

来自分类Dev

如何在IF或CASE WHEN语句中选择多个值

来自分类Dev

如何在CASE语句中分配多个值?

来自分类Dev

PostgreSQL重用CASE语句中长时间计算的值

来自分类Dev

在where子句中使用Case语句选择多个值

来自分类Dev

sql查询以再次获得case语句中的列值

来自分类Dev

如何在Postgres中的case语句中搜索空值

来自分类Dev

在SQL Server 2008中的case语句中排除值

来自分类Dev

oracle中where子句的case语句中传递多个值

Related 相关文章

热门标签

归档