Search code examples
sql-serverdivide-by-zero

SQL Server - Strange Divide By Zero


I'm executing the following query:

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

The important parts of function fn_Yval (all params are of type float):

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

The view vPolygonSegments contains no records where p1X = p2X (those records are excluded). Yet, when I execute my query, SQL Server returns an error: "Divide by zero error encountered." Curiously, if I execute only the first two lines (without the where clause), the query returns results just fine.

How do I fix this, and/or what is causing this behavior?

Edit: Here is my view:

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

Solution

  • The problem here is that the function in the select cause is evaluated before the function in the where clause is evaluated. This condition is very rare, but it is possible, so you need to code against it. I would suggest that you modify the function so that it can safely handle divide by zero circumstances. Change this line:

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

    To this:

    set @m = (@p2Y - @p1Y)/NullIf((@p2X - @p1X), 0)
    

    When @p2x - @p1x = 0, the NULLIF function will return NULL. Subsequently, @m will be null, as will all the other values. Most likely, the function will return NULL.

    In your where clause, you have...

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

    When the function returns NULL, it won't compare to 0 and will end up getting filtered out anyway.