Sql server 为什么IsNull会导致被零除的错误?
我有一个CTE作为长存储过程的一部分。我相信我有某种空传播错误。在试图精确定位它的位置时,我更改了一些代码,这导致了一个除以0的错误 这很好:Sql server 为什么IsNull会导致被零除的错误?,sql-server,Sql Server,我有一个CTE作为长存储过程的一部分。我相信我有某种空传播错误。在试图精确定位它的位置时,我更改了一些代码,这导致了一个除以0的错误 这很好: CalculatedMarks AS ( SELECT SessionsId, CourseName, StudentName, NoMark, Present, Late, [Absent], TotalMarks, TotalMarksPerPerson, ISNULL( str( (( 1.0 * [Absent] / isN
CalculatedMarks AS
(
SELECT SessionsId, CourseName, StudentName, NoMark, Present, Late, [Absent], TotalMarks, TotalMarksPerPerson,
ISNULL( str( (( 1.0 * [Absent] / isNull(TotalMarksPerPerson, 1) ) * 100), 3, 2), '') + '/'
+ ISNULL( str( (( 1.0 * Late / isNull(TotalMarksPerPerson, 1) ) * 100), 3, 2), '') + '/'
+ ISNULL( str( (( 1.0 * Present / isNull(TotalMarksPerPerson, 1) ) * 100), 3, 2), '' ) + '/'
+ str(TotalMarksPerPerson, 3, 2) AS Percentages
FROM AllData
)
但是,如果我改变了分子,因为可能这就是空值发挥作用的地方
CalculatedMarks AS (
SELECT SessionsId, CourseName, StudentName, NoMark, Present, Late, [Absent], TotalMarks, TotalMarksPerPerson,
ISNULL( str( (( 1.0 * isNull([Absent], 1) / isNull(TotalMarksPerPerson, 1) ) * 100), 3, 2), '') + '/'
+ ISNULL( str( (( 1.0 * isNull([Late], 1)/ isNull(TotalMarksPerPerson, 1) ) * 100), 3, 2), '') + '/'
+ ISNULL( str( (( 1.0 * isNull([Present], 1)/ isNull(TotalMarksPerPerson, 1) ) * 100), 3, 2), '' ) + '/'
+ str(TotalMarksPerPerson, 3, 2) AS Percentages
FROM AllData
)
我得到一个除以零的误差。我真的不确定我做错了什么,特别是因为分子不能导致被零除的错误。任何帮助都将不胜感激。谢谢。检查空值的一种方法
/ CASE WHEN isNull(TotalMarksPerPerson, 0) = 0 THEN 1 ELSE TotalMarksPerPerson END
当分子值都为空时,第一个有效。因为空值传播,所以永远不会执行除法,分母也不重要。在第二个查询中,通过将分母包装为isnull来消除这些空值,然后公开被零除 要验证我是否已在此处使用文本值设置了您的查询: 这与短路非常相似,尽管我认为有细微的区别。过去,SQL Server出现了许多与case表达式中的意外行为相关的错误,教训是您不能总是依赖于特定的求值顺序。在null传播的情况下,null/0是一个已定义的结果,它与跳过或不跳过冗余步骤的想法不同 试试这个:
CalculatedMarks AS (
SELECT
SessionsId,
CourseName,
StudentName,
NoMark,
Present,
Late,
[Absent],
TotalMarks,
TotalMarksPerPerson,
(Case When TotalMarksPerPerson = 0 Then Str(0, 3, 2) Else Str(([Absent] / TotalMarksPerPerson) * 100, 3, 2) End) + '/' +
(Case When TotalMarksPerPerson = 0 Then Str(0, 3, 2) Else Str(([Late] / TotalMarksPerPerson) * 100, 3, 2) End) + '/' +
(Case When TotalMarksPerPerson = 0 Then Str(0, 3, 2) Else Str(([Present] / TotalMarksPerPerson) * 100, 3, 2) End) + '/' +
Str(TotalMarksPerPerson, 3, 2) As Percentages
From
(
SELECT
SessionsId,
CourseName,
StudentName,
NoMark,
IsNull(Present, 0) As Present,
IsNull(Late, 0) As Late,
IsNull([Absent], 0) As [Absent],
IsNull(TotalMarks, 0) As TotalMarks,
IsNull(TotalMarksPerPerson, 0) As TotalMarksPerPerson,
FROM AllData
)
)
因为零不是空的。也许你的意思是nulliftTotalMarksperperson,0?那么,如果顶级查询工作正常,会有什么问题呢?第一个查询可能工作正常,因为分子值都是null。由于空值传播,因此实际上从未尝试过除法。在第二个查询中删除这些空值,然后暴露除以零,这可能是因为当其中一个分子的值为空时,缺少isnull会导致短路计算,因为生成的操作将始终为空。然后,通过强制它为1,整个表达式必须求值,结果是除以零??来回答null/0的问题,这类似于计算不确定分数0/0所需的解析演算,并且使用null的未知解释,您不能假设任何东西。如果您提前知道应该如何处理空分母情况,那么OP可能可以使用isNullIfValue、0、@properteReplacement。