Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.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 SQL Server-奇怪的除以零_Sql Server_Divide By Zero - Fatal编程技术网

Sql server SQL Server-奇怪的除以零

Sql server SQL Server-奇怪的除以零,sql-server,divide-by-zero,Sql Server,Divide By Zero,我正在执行以下查询: Select guiPolygonID, dbo.fn_Yval(p1X, p1Y, p2X, p2Y, 4.003318) From [vPolygonSegments] Where dbo.fn_Yval(p1X, p1Y, p2X, p2Y, 4.003318) > 0 函数fn_Yval的重要部分所有参数均为浮点型: set @m = (@p2Y - @p1Y)/(@p2X - @p1X) set @b = @p1Y - (@m*@p1X) set @res

我正在执行以下查询:

Select guiPolygonID, dbo.fn_Yval(p1X, p1Y, p2X, p2Y, 4.003318)
From [vPolygonSegments]
Where dbo.fn_Yval(p1X, p1Y, p2X, p2Y, 4.003318) > 0
函数fn_Yval的重要部分所有参数均为浮点型:

set @m = (@p2Y - @p1Y)/(@p2X - @p1X)
set @b = @p1Y - (@m*@p1X)
set @result = (@m*@xval+@b)

视图vPolygonSegments不包含任何记录,其中p1X=p2X不包括这些记录。然而,当我执行查询时,SQLServer返回一个错误:遇到被零除的错误。奇怪的是,如果我只执行前两行而不执行where子句,那么查询返回的结果就很好

如何修复此问题,和/或导致此行为的原因是什么

编辑: 以下是我的看法:

Select P1.guiPolygonID,
    P1.decX as p1X, P1.decY as p1Y,
    P2.decX as p2X, P2.decY as p2Y
From PolygonPoints P1, PolygonPoints P2
Where P1.guiPolygonID = P2.guiPolygonID
    and (
        P1.lPointNumber - P2.lPointNumber = 1
        or (
            -- Some other unimportant code
        )
    )
    and P1.decX <> P2.decX

当@p2X=@p1X时出现问题。你认为在这种情况下会发生什么?

正如乔尔·科霍恩所指出的,这是可能的问题。下面的查询应该可以避免此问题,但最好在函数本身内部解决此问题:

Select guiPolygonID, dbo.fn_Yval(p1X, p1Y, p2X, p2Y, 4.003318)
From [vPolygonSegments]
Where p2X <> p1X and dbo.fn_Yval(p1X, p1Y, p2X, p2Y, 4.003318) > 0

我不知道这会以任何方式回答这个问题,但你会对每一张记录评估fn_Yval两次。为什么不将函数的结果设置为视图中的一列?然后,where子句可能类似于where Yval>0


编辑:出于好奇,fn_Yval没有任何副作用,是吗?

我发现当涉及连接或视图时,尝试使用where子句删除可能导致除零错误的数据是有问题的。在join子句中筛选数据,或在函数中筛选出数据


更新:正是因为G·马斯特罗斯写的那种原因

这里的问题是,在计算where子句中的函数之前,先计算select cause中的函数。这种情况非常罕见,但这是可能的,因此您需要针对它编写代码。我建议您修改该函数,以便它能够安全地处理除法为零的情况。更改此行:

set @m = (@p2Y - @p1Y)/(@p2X - @p1X)
为此:

set @m = (@p2Y - @p1Y)/NullIf((@p2X - @p1X), 0)
当@p2x-@p1x=0时,NULLIF函数将返回NULL。随后,@m和所有其他值都将为null。该函数很可能返回NULL

在where子句中,您有

Where dbo.fn_Yval(p1X, p1Y, p2X, p2Y, 4.003318) > 0

当函数返回NULL时,它将不会与0进行比较,并且最终会被过滤掉。

我怀疑这与查询的视图具体化方式有关。将该函数添加到where子句实际上是将其添加到视图的源查询中,这样优化器可能会选择将此过滤器应用到P1.decX P2.decX之前的源数据


无论如何,您不知道什么时候需要在其他没有相同约束的地方重新使用该函数。最好事先制定一个如何处理坏数据的计划。在这种情况下,NullIf建议似乎是个不错的建议。

。。但是他正在删除这些数据点,而且在这种情况下,选择是否也会失败-当删除位置时?或者这些数据点没有删除,或者我们没有所有相关的代码。在他发布的代码中,这些数据是在哪里删除的?当然不是where子句!我知道他是这么说的,但不管怎样,这就是正在发生的事情。。。除非您能指出该查询中的另一个除法运算,其分母中可能为0。奇怪的是,如果我只执行前两行而不执行where子句,则查询返回的结果很好。-这意味着这种情况不会发生?奇怪的我仍然不明白为什么它会中断,可能是预计算或其他什么,但您的解决方案解决了问题。我也不明白-这就是为什么我建议您使用防弹功能。同意您的看法。我从来没有写过任何使用除法的代码,如果不确定它能处理零值的情况。如果你使用这个函数来确定线段的角度,并且你的点在纬度/经度坐标系中,那么你会遇到更大的问题。问题是纬度的一度变化与经度的一度变化的距离不同。