2013-08-22 88 views
1

我想获得两点之间的距离,也能正常工作,但什么我有问题是这些警告消息:数据截断列“X”

数据被截断列“X”在列32
数据被截断为列“X”在列82
数据被截断为列“X”在列89

这是我所创建的功能:

CREATE FUNCTION `GetDistance`(`lat1` numeric(10, 7), `lon1` numeric(10, 7), `lat2` numeric(10, 7), `lon2` numeric(10, 7)) 
RETURNS decimal(10,7) 
BEGIN 
     DECLARE x decimal(10, 7); 
     DECLARE pi decimal(21, 20); 
     SET pi = 3.14159265358979323846; 
     SET x = round(sin(lat1 * pi/180) 
     * sin(lat2 * pi/180) 
     + cos(lat1 * pi/180) 
     * cos(lat2 * pi/180) 
     * cos((lon2 * pi/180) - (lon1 * pi/180)), 7); 
    SET x = round(atan((sqrt(1- power(x, 2)))/x), 7); 
    RETURN round((1.852 * 60.0 * ((x/pi) * 180))/1.609344, 7); 
END 

下面是lat1lon1lat2两列,lon2

CREATE TABLE `world_cities` (
    `latitude` DECIMAL(10,7) NULL DEFAULT NULL, 
    `longitude` DECIMAL(10,7) NULL DEFAULT NULL, 
) 

这里有最大/最小值:

"max(latitude)"  "min(latitude)"  "max(longitude)"  "min(longitude)" 
"82.4833330"  "-54.9333330"  "180.0000000"  "-179.9833333" 

那么,是什么原因造成这种警告信息吗?

下面是该查询调用该函数:

SELECT city, region, population, latitude, longitude, 
GetDistance(@lat, @lon, latitude, longitude) as dist 
FROM world_cities 
WHERE MBRContains(LineString(Point(@lat + @kmRange/111.1, @lon + @kmRange/(111.1/COS(RADIANS(@lat)))), Point(@lat - @kmRange/111.1, @lon - @kmRange/(111.1/COS(RADIANS(@lat))))), location) 
and city_id != @city_id 
order By dist; 

回答

0

通过声明'x'为double,并将返回类型设置为double我能够解决此问题。

更改此:

DECLARE x decimal(10, 7); 

要这样:

DECLARE x double; 
0

将返回RETURNS decimal(10,7),并在同一时间计算距离,该距离远远超过decimal(10,7)
arctan(a)的值应在-pi/2pi/2-1.57 ... 1.57)之间。
我们假设x = pi/2,所以x/pi = (pi/2)/pi = 1/2
您的距离值将超过6000,该值大于decimal(10,7)

尝试将RETURNS decimal(10,7)更改为RETURNS decimal(11,7),它应该涵盖所有可能的值并且在没有警告的情况下工作。

+0

不,改变仍然给我的警告。 –

+0

@Alex这实际上是一个问题,但我意识到它会导致“超出范围值列......”警告,而不是“数据截断”。 – jaeheung

0

请试试这个:

CREATE FUNCTION `GetDistance`(`lat1` numeric(10, 7), `lon1` numeric(10, 7), `lat2` numeric(10, 7), `lon2` numeric(10, 7)) 
RETURNS decimal(10,7) 
BEGIN 
     DECLARE x decimal(10, 7); 
     DECLARE pi decimal(21, 20); 
     SET pi = 3.14159265358979323846; 
     SET x = cast(sin(lat1 * pi/180) 
     * sin(lat2 * pi/180) 
     + cos(lat1 * pi/180) 
     * cos(lat2 * pi/180) 
     * cos((lon2 * pi/180) - (lon1 * pi/180)) as decimal(10, 7)); 
    SET x = cast(atan((sqrt(1- power(x, 2)))/x) as decimal(10, 7)); 
    RETURN cast((1.852 * 60.0 * ((x/pi) * 180))/1.609344 as decimal(10, 7)); 
END 

我怀疑浮点逼近误差。