如何防止存储过程中的被零除错误?

时间:2016-01-13 18:11:43

标签: sql-server tsql stored-procedures division date-math

我尝试从服务器资源管理器中执行my brand-spanking-new Stored Procedure,我得到了:

Msg 8134,Level 16,State 1,Procedure duckbilledPlatypi,Line 13 遇到零错误。

以下是涉及的行(13):

@Week1End Week1End,

......在更多背景下:

DECLARE 
@Week1End datetime,
@Week2begin datetime

Select Ind.Description,
    @BegDate  BegDate,
    @Week1End Week1End,
    @Week1End Week2Begin,
    @EndDate EndDate,

对于完整的披露/背景,这里是整个SP,因为它现在存在:

CREATE PROCEDURE [dbo].[duckbilledPlatypi]
    @Unit varchar(25),
    @BegDate datetime,
    @EndDate datetime
AS

DECLARE 
@Week1End datetime,
@Week2begin datetime

Select Ind.Description,
    @BegDate  BegDate,
    @Week1End Week1End,
    @Week1End Week2Begin,
    @EndDate EndDate,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.QtyShipped ELSE 0 END) 
Week1Usage,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.QtyShipped ELSE 0 END) 
Week2Usage,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) 
Week1Price,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.Price ELSE 0 END) -
   SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.QtyShipped ELSE 0 END) 
UsageVariance,
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.QtyShipped ELSE 0 END)  -
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) 
PriceVariance,
    (SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.QtyShipped ELSE 0 
END)  -
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) )
    / SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) 
PercentageOfPriceVariance
    From    InvoiceDetail Ind
    Where   Ind.Unit = @Unit
    AND Ind.InvoiceDate BETWEEN @BegDate AND @EndDate
    Group By Ind.Description

我的猜测是@ Week1End Week1End失败了,因为它没有给出值,因此是null。我不知道我是否应该这样做以防止0 /空:

DECLARE 
@Week1End datetime = BegDate + 6;
@Week2begin datetime = BegDate + 7;

......或类似的东西:

Select Ind.Description,
    @BegDate  BegDate,
    @Week1End BegDate+6,
    @Week2Begin BegDate+7,
    @EndDate EndDate,

......或其他完全不同的东西。

你可能会说,我不知道日期数学应该如何实现。日期真正需要的是:

Week1Begin is the "BegDate" the user provided as a parameter
Week1End needs to be six days after Week1Begin
Week2Begin needs to be seven days after Week1Begin
Week2End is the "EndDate" the user provided as a parameter
例如,如果用户输入" 12/27/2015" BegDate和" 2016年1月6日"对于EndDate,这些值必须是:

Week1Begin = 12/27/2015
Week1End = 1/2/2016
Week2Begin = 1/3/2016
Week2End = 1/6/2016 (week2 is only a four-day week in this case, due to what the user entered)

我该怎样做才能确保此处没有零点?

1 个答案:

答案 0 :(得分:2)

您可以使用NULLIF

   (SUM(CASE WHEN Ind.InvoiceDate BETWEEN @Week2Begin AND @EndDate THEN Ind.QtyShipped ELSE 0 
END)  -
    SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END) )
    / NULLIF(SUM(CASE WHEN Ind.InvoiceDate BETWEEN @BegDate AND @Week1End THEN Ind.Price ELSE 0 END),0) 
PercentageOfPriceVariance

因此,当除数为0时,enitre结果为NULL。如果您需要特殊值,请添加COALESCE

COALESCE(exp1 / NULLIF(exp2, 0), special_value) AS result

LiveDemo