Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 为什么IsNull会导致被零除的错误?_Sql Server - Fatal编程技术网

Sql server 为什么IsNull会导致被零除的错误?

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

我有一个CTE作为长存储过程的一部分。我相信我有某种空传播错误。在试图精确定位它的位置时,我更改了一些代码,这导致了一个除以0的错误

这很好:

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。