SQL Server“发生了无效的浮点运算”

时间:2012-01-06 15:57:48

标签: sql sql-server sql-server-2008

这不是一个真正的问题,因为我解决了它。但是,我想分享今天吃掉我大脑的东西。因此,运行此查询并检查出来:

查询:

select 2 as ID1,0 as ID2 into #TEMP
insert into #TEMP (ID1,ID2)
values (2,1),(2,2),(2,0)

select
  case when min(case when ID1=2 and ID2=0 then 0
                     else 1
                end)=0 then 0
       else sum(log(ID2))
  end
from #TEMP

修复:

select
  case when min(case when ID1=2 and ID2=0 then 0
                     else 1
                end)=0 then 0
       else sum(log(case when ID1=2 and ID2<>0 then ID2
                         else 1
                    end))
  end
from #TEMP

我的查询更大,更难以调试,但您对MSSQL正在制定的计划以及它在此查询中出错的事实怎么说?除了我之前展示的一点点修复之外,怎样才能修改它?我猜测,如果标量不易计算并且我们计算所有值,那么在查询之前计算标量会使事情变慢。

2 个答案:

答案 0 :(得分:2)

SQL Server不执行短路评估(即不应该依赖)。这是一个众所周知的问题。

参考:

答案 1 :(得分:1)

编辑:我用原来的答案误解了这个问题。

我猜你可以添加一个where子句,如下所示。附注:此查询可能会受益于(ID1,ID2)上的索引。

select
  sum(log(convert(float, ID2)))
from #TEMP
where
    -- exclude all records with ID1 = 2 if there are any records with ID1 = 2 and ID2 = 0
    not exists (
        select 1
        from #TEMP NoZeros
        where
            NoZeros.ID1 = #TEMP.ID1
            and NoZeros.ID2 = 0
    )

更新:为了防止性能问题,我在添加以下索引后获得了与此查询相当的性能:

create index ix_TEMP_ID1_ID2 on #TEMP (ID1, ID2)
create index ix_TEMP_ID2 on #TEMP (ID2) include (ID1)

原始答案

如下所示修改sum功能怎么样?

sum(case ID2 when 0 then null else log(convert(float, ID2)) end)