【问题标题】:Divide by zero error returns for queries with no data对于没有数据的查询,除以零错误返回
【发布时间】:2014-02-14 09:59:34
【问题描述】:

我正在尝试找出解决这个除以零错误的方法。我目前面临的挑战来自this question I asked not too long ago.

这是我正在使用的代码,我将其插入到年底的报告中:

SELECT CAST(ROUND((.01 * 2541) / Count(date_record_entered), 1) AS decimal(5,1)) 
FROM dbo.tablename
WHERE date_record_entered IS NOT NULL 
and date_record_entered >= 20131201 
AND date_record_entered <= 20131231

对于当前或前几个月的报告,数据填充没有任何问题。但是,当访问超过当月的报告时,我在 SQL 中收到以下错误(在 C#/ASP.NET 中也出现类似错误):

Msg 8134, Level 16, State 1, Line 1
Divide by zero error encountered

这是我尝试过但没有成功的方法。

示例 #1

SELECT CASE WHEN date_record_entered = 0 then null
ELSE CAST(ROUND(.01 * 2541 / COUNT(date_record_entered), 
AS deciamal (5,1)
FROM dbo.tablename 
WHERE date_record_entered IS NOT NULL 
AND date_record_entered >= 20140201 
and date_record_entered <= 20140228

示例 #2

SELECT CAST(ROUND((.01 * 2541) / NULLIF(Count(date_record_entered), 1) 
AS decimal(5,1))) 
FROM dbo.tablename 
WHERE date_record_entered IS NOT NULL 
and date_record_entered >= 20140201 
AND date_record_entered <= 20140228

样本 #3

SET ARITHABORT OFF
SET ANSI_WARNINGS OFF

SELECT CAST(ROUND(.01 * 2541 / COUNT(date_record_entered ), 1) AS decimal(5,1)) 
FROM dbo.tablename  
WHERE date_record_entered IS NOT NULL 
AND date_record_entered >= 20140201 
and date_record_entered  <= 20140228

现在第三个可以在 SQL 中使用,但我还没有找到使用 gridview/c# 的方法。

我知道这可能非常简单,但我现在只是在旋转我的轮子。

【问题讨论】:

  • 一些回车会使代码更容易阅读。
  • 在末尾添加一个HAVING Count(date_record_entered) &gt; 0 怎么样?由于您似乎正在检查 date_record_entered = 0 但除以 Count(date_record_entered)
  • 为什么 date_record_entered 永远是 0?如果该字段是数据库中的日期字段,那么我认为这是不可能的,它要么是日期,要么是空值。所以如果是这样的话,我会在你的案例陈述中检查它是否为空。
  • 你所有的样本都有语法错误。
  • @drewlander date_record_enteredCOUNT() 由于 WHERE 标准可能为 0。

标签: c# asp.net sql gridview sql-server-2012


【解决方案1】:

样本 2 有:NULLIF(Count(date_record_entered), 1)

改为尝试:NULLIF(Count(date_record_entered), 0)

NULLIF 将返回第一个参数中的值,除非它等于第二个参数中的值。如果它们相等,则 NULLIF 返回 NULL。

SELECT CAST(ROUND((.01 * 2541) / NULLIF(Count(date_record_entered), 1), 0) AS decimal(5,1))
FROM dbo.tablename 
WHERE date_record_entered IS NOT NULL 
and date_record_entered >= 20140201 
AND date_record_entered <= 20140228

【讨论】:

  • 我将其插入并得到“'关键字'AS'附近的语法不正确。”
  • 我只是建议您将 1 更改为 0。我假设您的查询在语法上已经正确。无论如何,我已经用完整的查询更新了我的答案。
【解决方案2】:

使用NULLIF() 有效,因为除以NULL 返回NULL

SELECT CAST((.01 * 2541) / NULLIF(COUNT(date_record_entered), 0) AS DECIMAL(5,1)) 
FROM dbo.tablename
WHERE date_record_entered >= 20131201 
  AND date_record_entered <= 20131231

使用CASE

SELECT CASE WHEN COUNT(date_record_entered) = 0 THEN NULL
            ELSE CAST((.01 * 2541) / COUNT(date_record_entered) AS DECIMAL(5,1))
       END
FROM dbo.tablename 
WHERE date_record_entered >= 20140201 
  AND date_record_entered <= 20140228

通常可以避免抑制警告。 date_record_entered 永远不能同时是 NULL 并且介于两个日期之间,所以我删除了 WHERE 标准的那一部分。

【讨论】:

  • 看起来,如果计数为 1,您的 NULLIF 函数将返回 null。我认为如果计数为 0,则需要将其更改为返回 null(这将导致除以零错误)。
  • @GMastros 啊,谢谢,ROUNDNULLIF 翻转,意味着完全删除 ROUND()。已更新。
【解决方案3】:

第二个解决方案不应该是……

SELECT CASE WHEN COUNT(date_record_entered) = 0 then null ELSE CAST(ROUND(.01 * 2541 / COUNT(date_record_entered), AS decimal (5,1)) END FROM dbo.tablename WHERE date_record_entered IS NOT NULL AND date_record_entered &gt;= 140201 and date_record_entered &lt;= 140228

在 CASE WHEN 中使用 COUNT()

【讨论】:

  • 这就是我的意思。感谢您说得更清楚。
  • 这会返回“关键字'FROM'附近的语法错误”。
猜你喜欢
  • 2014-08-25
  • 1970-01-01
  • 2021-06-01
  • 1970-01-01
  • 2014-04-08
  • 1970-01-01
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
相关资源
最近更新 更多