我正在编写一个TSQL过程,并有一个提取数据的查询。但是,它返回零除错误异常

时间:2019-08-31 13:26:07

标签: sql-server tsql isnull

尽管我在代码中使用了ISNULL,但是从下面的代码中将错误零除。有关如何解决此问题的任何建议。

SELECT 
    dd.detail_id DETAIL_ID, dd.period_id PERIOD_ID, noff.FGA_ID FGA_ID,
    noff.fulfillment_center FULFILLMENT_CENTER, noff.DEMAND_TYPE DEMAND_TYPE,
    noff.LEGACY_SSC LEGACY_SSC,
    noff.net_offset_forecast NET_OFFSET_FORECAST,
    noff.forecast_to_be_consumed FORECAST_TO_BE_CONSUMED,
    CASE 
       WHEN ISNULL(dd.DEPOT_WISE_FORECAST, 0) = 0 
          THEN 0 
          ELSE (noff.net_offset_forecast * dd.detail_depot_wise_forecast) / ISNULL((dd.agg_depot_wise_forecast), 0))
    END detail_forecast_consumption,
    CASE 
       WHEN ISNULL(dd.DEPOT_WISE_FORECAST, 0) = 0 
          THEN 0 
          ELSE (noff.FORECAST_TO_BE_CONSUMED * dd.detail_depot_wise_forecast) / ISNULL((dd.agg_depot_wise_forecast), 0))
    END detail_forecast_sales
INTO 
    aggregate_to_detail_forecast_consumption                          
FROM 
    net_offset_forecast noff 
JOIN
    disaggregate_data dd ON noff.fga_id = dd.snop_item  
                         AND noff.fulfillment_center = dd.fulfillment_center 

SELECT 
    dd.detail_id DETAIL_ID, dd.period_id PERIOD_ID, noff.FGA_ID FGA_ID,
    noff.fulfillment_center FULFILLMENT_CENTER,
    noff.DEMAND_TYPE DEMAND_TYPE, noff.LEGACY_SSC LEGACY_SSC,
    noff.net_offset_forecast NET_OFFSET_FORECAST,
    noff.forecast_to_be_consumed FORECAST_TO_BE_CONSUMED,
    CASE 
       WHEN ISNULL(dd.DEPOT_WISE_FORECAST, 0) = 0
          THEN 0 
          ELSE (noff.net_offset_forecast * dd.detail_depot_wise_forecast) / ISNULL((dd.agg_depot_wise_forecast), 0))
    END detail_forecast_consumption,
    CASE 
       WHEN ISNULL(dd.DEPOT_WISE_FORECAST, 0) = 0 
          THEN 0 
          ELSE (noff.FORECAST_TO_BE_CONSUMED * dd.detail_depot_wise_forecast) / ISNULL((dd.agg_depot_wise_forecast), 0))
    END detail_forecast_sales
INTO 
    aggregate_to_detail_forecast_consumption                          
FROM 
    net_offset_forecast noff 
JOIN
    disaggregate_data dd ON noff.fga_id = dd.snop_item  
                         AND noff.fulfillment_center = dd.fulfillment_center 

上面的代码应该没有被零除的异常

3 个答案:

答案 0 :(得分:2)

您不想要/ ISNULL(dd.agg_depot_wise_forecast, 0)

这将返回dd.agg_depot_wise_forecast0,具体取决于第一个参数是NULL

您要使用NULLIF()/ NULLIF(dd.agg_depot_wise_forecast, 0)

这将用NULL替换零值,从而避免了错误。

答案 1 :(得分:0)

您应该检查该值,并且当它为NULL时不要尝试顶部除法。当它为NULL时,您将其替换为0,并导致被零除的错误。 这是一个示例:

declare @sample table (id int identity, v1 decimal(10,2), v2 decimal(10,2) null);

insert into @sample (v1, v2) values 
(10,2),
(10,null);

--select *, v1/isnull(v2,0)
--from @sample;

select *, case when v2 is null then 0 else v1/v2 end as MyVal
from @sample;

有评论的部分是您的操作方式并会出错。

答案 2 :(得分:0)

请用以下更正后的案例声明替换您的案例声明。

更改: ISNULL((dd.agg_depot_wise_forecast),0)-> ISNULL(NULLIF(dd.agg_depot_wise_forecast,0),1)

NULLIF()将0值替换为NULL值,因此ISNULL()将始终从第二个参数中获取1。

memcpy