我有一个存储过程,它计算两个坐标对之间的距离作为浮点数。我尝试使用它来过滤值列表但得到算术溢出错误。查询是:
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
还尝试将结果转换为十进制,但没有效果。
答案 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)
你回来了一个漂浮物。您是否应该使用浮点数作为纬度和经度变量?