下面的TSQL应该随机生成20行,其中包含递增ID和星期几。 See this in action here
注意:我知道这段代码已经存在缺陷我只是在玩一个想法。
declare @loop int = 1;
if OBJECT_ID('tempdb..#temp') is not null drop table #temp;
create table #temp(id int, dayofweek varchar(10))
while @loop < 21
begin
insert into #temp
values(@loop, case ceiling(rand()*7)
when 1 then 'Monday'
when 2 then 'Tuesday'
when 3 then 'Wednesday'
when 4 then 'Thursday'
when 5 then 'Friday'
when 6 then 'Saturday'
when 7 then 'Sunday'
end)
set @loop += 1
end
如果我select * from #temp
我在查询结果中获得了一些NULL值,那就是'dayofweek&#39;柱。任何人都可以解释为什么会这样吗?我查看了ceiling(rand()*7)
的返回结果,据我所知,它只会返回1到7之间的结果。
我错过了什么?
答案 0 :(得分:7)
这非常微妙。问题是每次比较都会对case表达式进行一次评估。因此,有时所有的比较都会失败,因为它们使用不同的数字。
隐藏在documentation中的是这个说明:
- 评估input_expression,然后按照指定的顺序,为每个WHEN子句计算input_expression = when_expression。
这更令人惊讶,因为rand()
通常不会多次评估(至少在select
,set
或where
条款中。在这种情况下,似乎是。幸运的是,有一个简单的解决方法:
declare @loop int = 1;
declare @dow int;
if OBJECT_ID('tempdb..#temp') is not null drop table #temp;
create table #temp(id int, dayofweek varchar(10))
while @loop < 21
begin
set @dow = ceiling(rand()*7);
insert into #temp
values(@loop, case dow
when 1 then 'Monday'
when 2 then 'Tuesday'
when 3 then 'Wednesday'
when 4 then 'Thursday'
when 5 then 'Friday'
when 6 then 'Saturday'
when 7 then 'Sunday'
end)
set @loop += 1;
end;