SQL Server中的算术溢出

时间:2011-06-11 14:32:45

标签: sql sql-server math

我有一个存储过程,它计算两个坐标对之间的距离作为浮点数。我尝试使用它来过滤值列表但得到算术溢出错误。查询是:

SELECT * FROM Housing h  WHERE convert(float, dbo.CalculateDistance(35, -94, h.Latitude, h.Longitude)) <= 30.0

哪些错误:

  

Msg 8115,Level 16,State 6,Line 1算术溢出错误   将float转换为数据类型numeric。

存储过程供参考:

CREATE FUNCTION [dbo].[CalculateDistance]
    (@Longitude1 DECIMAL(8,5),
    @Latitude1   DECIMAL(8,5),
    @Longitude2  DECIMAL(8,5),
    @Latitude2   DECIMAL(8,5))
RETURNS FLOAT
AS
BEGIN
DECLARE @Temp FLOAT

SET @Temp = SIN(@Latitude1/57.2957795130823) * SIN(@Latitude2/57.2957795130823) + COS(@Latitude1/57.2957795130823) * COS(@Latitude2/57.2957795130823) * COS(@Longitude2/57.2957795130823 - @Longitude1/57.2957795130823)

IF @Temp > 1
    SET @Temp = 1
ELSE IF @Temp < -1
    SET @Temp = -1

RETURN (3958.75586574 * ACOS(@Temp) )

END

还尝试将结果转换为十进制,但没有效果。

4 个答案:

答案 0 :(得分:4)

您的输入是DECIMAL(8,5)。这意味着方程式由例如SIN(DECIMAL(8,5) / 57.2957795130823)组成。其中57.2957795130823不能表示为DECIMAL(8,5)。

这意味着由于数据类型不同,您有一个隐含的CAST操作。在这种情况下,似乎57.2957795130823被转换为DECIMAL(8,5)[数字],并导致溢出。

我会推荐以下任何一种:
- 改变您的功能以将输入作为FLOATS。即使用数字调用函数
- 将57.2957795130823更改为57.29577
- 明确地将DECIMAL投射到FLOATs

答案 1 :(得分:1)

我会尝试转换我的一些算术以防万一

convert(float,(SIN(@Latitude1/57.2957795130823)) * convert(float,(SIN(@Latitude2/57.2957795130823)) + convert(float,(COS(@Latitude1/57.2957795130823)) * convert(float,(COS(@Latitude2/57.2957795130823)) * convert(float,COS(@Longitude2/57.2957795130823 - @Longitude1/57.2957795130823))

你可以使用的另一件事是

IFNULL(convert(float,(SIN(@Latitude1/57.2957795130823)),0.00)

您的结果可能会返回空值

答案 2 :(得分:1)

这是与&lt; = 30.0

的比较

30.0是十进制(3,2)(小数点的常量在SQL Server中是十进制的)并且不会转换浮点输出。见:

SELECT 30.0 AS What INTO dbo.DataType
Go
SELECT t.name, c.*
FROM sys.columns c JOIN sys.types t ON c.system_type_id = t.system_type_id
WHERE object_id = OBJECT_ID('dbo.DataType')
GO
DROP TABLE dbo.DataType
GO

尝试

... <= CAST(30.0 As float)

答案 3 :(得分:0)

你回来了一个漂浮物。您是否应该使用浮点数作为纬度和经度变量?