Mat*_*son 3 sql t-sql sql-server
下面的TSQL应该随机生成20行,其中包含递增ID和星期几. 在这里看到这个.
注意:我知道这段代码已经存在缺陷我只是在想一个想法.
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
Run Code Online (Sandbox Code Playgroud)
如果我这样做select * from #temp
,我在'dayofweek'列的查询结果中得到一些NULL值.任何人都可以解释为什么会这样吗?我已经查看了返回结果,ceiling(rand()*7)
据我所知,它只返回1到7之间的结果.
我错过了什么?
这非常微妙.问题是每次比较都会对case表达式进行一次评估.因此,有时所有的比较都会失败,因为它们使用不同的数字.
文件中埋藏的是这个说明:
- 计算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;
Run Code Online (Sandbox Code Playgroud)