当我执行我的存储过程时,它会抛出Divide By zero Exception。因为在我的数据库中,几个月没有数据。我该如何解决这个问题?
以下是我的询问。
@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
是列名。 rn
rownumber.descrn
也是递减顺序的行号。
如何修改我的查询?
请回复。
此致
NSJ
答案 0 :(得分: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
的情况下使用它,在这种情况下,我稍后使用更复杂的逻辑处理可能的NULL结果。
SELECT
@Var1 = expression1,
@Var2 = expression2,
...
这可能会帮助您简化查询吗?
答案 1 :(得分:1)
你的表达非常清楚,难以理解,而且你选择相同的值几次是完全没必要的 - 所以我的推荐是:
尝试首先确定可能进入您计算的所有部分 - 将select top 1 ....
个查询的结果放入变量中
然后检查,然后除以零,如果除数为零,则需要考虑使用另一个解决方案/另一个值...
< / LI>你的问题是这样的:你目前只检查你的一个值是< 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
答案 2 :(得分:0)
也许你的if子句需要'&lt; = 0'而不是'&lt; 0'?您还应该确保临时表中的数据符合rn = 1条件,否则选择将返回null。如果所有其他方法都失败了,Sql2005会尝试使用catch块,因此您可以捕获除以零的异常。