2011-02-02 61 views
0

當我執行我的存儲過程時,它將拋出Divide By zero Exception。因爲在我的數據庫中有幾個月沒有數據。我該如何解決這個問題?如何解決SQL存儲過程中的Divide by Zero異常?

下面是我的查詢。

@diffNSVY FLOAT = 0  --I have declared @diffNSVY as optional parameter. 

SET @diffNSVY = CASE 
     WHEN (select top 1 NSV from #temp where rn = 1) < 0 THEN 0 
      ELSE (((select top 1 NSV from #temp where descrn = 1) - (select top 1 NSV from #temp where rn = 1))*1.0)/(select top 1 NSV from #temp where rn = 1) 
     END 

我將結果集插入到#temp表中。 NSV是一個列名。 rnrownumber.descrn也是按降序排列的行號。

如何修改我的查詢?

請回復。

問候,

NSJ

回答

0

也許你在你的if語句需要一個 '< = 0' 而不是 '< 0'?您還應該確保臨時表中的數據滿足rn = 1條件,否則選擇將返回空值。如果一切都失敗Sql2005已經嘗試catch塊,所以你可以通過零異常捕獲除數。

+0

你可以發送示例try --- catch實現上述查詢嗎? – sriramjitendra 2011-02-02 06:35:58

1

你那表情是非常不清楚,很難理解,而你選擇的值相同幾次這是完全不必要的 - 所以我的建議是:

  • 儘量先確定所有可能會變成你測算的點點滴滴 - 把那些select top 1 ....查詢結果到變量

  • 然後檢查你除以零之前,如果你除數將是零,你需要考慮的另一個解決方案/另一個值來使用。 ..

你的問題是這樣的:你目前只能檢查你的一個價值是< 0,然後你的回報0 - 否則(包括當值= 0),你返回的是一個部門一個表達式確切的值....你需要添加一個特殊情況:如果該值是= 0,你不能使用你的表達式,因爲這會導致被零除異常 - 在這種情況下你需要返回一些其他值!

所以,你的代碼將是這樣的:

DECLARE @diffNSVY FLOAT = 0  --I have declared @diffNSVY as optional parameter. 

DECLARE @RNValue INT 
SET @RNValue = (SELECT TOP 1 NSV FROM #temp WHERE rn = 1) 

DECLARE @DescRNValue INT 
SET @DescRNValue = (SELECT TOP 1 NSV FROM #temp WHERE descrn = 1) 


SET @diffNSVY = 
    CASE 
     WHEN @RNValue < 0 THEN 0 
     WHEN @RNValue = 0 THEN ....... <-- you need to define a value here! CAnnot divide by @RNValue if it's ZERO ! 
     ELSE ((@DescRNValue - @RNValue) * 1.0)/@RNValue 
    END 
+0

嗨,先生。謝謝回覆。沒關係。 但我有35個查詢像上面的查詢。我再次聲明可選參數。 有沒有其他解決方案? 問候, NSJ – sriramjitendra 2011-02-02 06:36:28

2

第一,所以我沒必要重複複雜的表達式(該子查詢,要準確)不止一次我會重建你的腳本。

如果可能的話,使用SELECT而不是SET,像這樣:

SELECT @diffNSVY = CASE 
    WHEN rn.NSV < 0 THEN 0 
    ELSE (descrn.NSV - rn.NSV) * 1.0/rn.NSV /* extra '()' are removed as unneeded */ 
FROM 
    (select top 1 NSV from #temp where rn = 1) AS rn, 
    (select top 1 NSV from #temp where descrn = 1) AS descrn 

接下來,問問自己,結果應該是什麼在分裂的情況下,通過零。它是否應該爲零?然後下一個優化步驟是簡單:

SELECT @diffNSVY = CASE 
    WHEN rn.NSV <= 0 THEN 0 /* changed '<' to '<=' to account for division by zero */ 
    ELSE (descrn.NSV - rn.NSV) * 1.0/rn.NSV 
FROM 
    (select top 1 NSV from #temp where rn = 1) AS rn, 
    (select top 1 NSV from #temp where descrn = 1) AS descrn 

但是如果你希望結果是不確定的(NULL),所以你以後再處理它,這裏是你如何能做到這一點:

SELECT @diffNSVY = CASE 
    WHEN rn.NSV < 0 THEN 0 
    ELSE (descrn.NSV - rn.NSV) * 1.0/CASE rn.NSV WHEN 0 THEN NULL ELSE rn.NSV END 
FROM 
    (select top 1 NSV from #temp where rn = 1) AS rn, 
    (select top 1 NSV from #temp where descrn = 1) AS descrn 

一般,當我需要確保自己不會受到零分錯誤時,我發現這種模式很有用。我經常用這樣的:

...ISNULL(some_expression/CASE @Value WHEN 0 THEN NULL ELSE @Value END, 0)... 

有時我使用它,而ISNULL在這種情況下,我處理可能的空結果後使用一些更復雜的邏輯。

編輯:哦,還有一兩件事:用SELECT您可以一次有幾個任務,像這樣:

SELECT 
    @Var1 = expression1, 
    @Var2 = expression2, 
    ... 

難道這可能會幫助您簡化您的查詢呢?

相關問題