MySQL 存储函数出现故障,但作为独立查询运行
MySQL stored function malfunctioning, but working as standalone query
我有一个基本查询,基于 this discussion 计算两个坐标之间的距离。
它似乎 运行 作为独立查询很好,但是当我尝试 运行 它作为存储函数时,它 return 奇怪的结果(通常为 null 或 99.9999...)。
独立查询是:
SELECT lat, lng,
( 6371 * acos( cos( radians(32.113277) ) * cos( radians( lat ) )
* cos( radians(lng) - radians(34.799259)) + sin(radians(32.113277))
* sin( radians(lat)))) AS distance_km,
( 6371000 * acos( cos( radians(32.113277) ) * cos( radians( lat ) )
* cos( radians(lng) - radians(34.799259)) + sin(radians(32.113277))
* sin( radians(lat)))) AS distance_meters
FROM (
SELECT 32.113391 as lat , 34.801571 as lng
) a
^ 这个 运行 没问题。然后我尝试将其更改为存储函数:
create function distance_meters(lat1 decimal(8,6), lng1 decimal(8,6), lat2 decimal(8,6), lng2 decimal(8,6) )
returns decimal(8,6) DETERMINISTIC
return ( 6371000 * acos( cos( radians(lat1) ) * cos( radians( lat2 ) )
* cos( radians(lng2) - radians(lng1)) + sin(radians(lat2))
* sin( radians(lat2))))
并像这样执行它:
select distance_meters(32.113277, 34.799259, 32.113391, 34.801571)
结果为 99.999999
我什至尝试将所有输入值(用于坐标)作为存储函数代码的一部分,如下所示:
create function distance_meters()
returns decimal(8,6) DETERMINISTIC
return ( 6371000 * acos( cos( radians(32.113277) ) * cos( radians( 32.113391 ) )
* cos( radians(34.801571) - radians(34.799259)) + sin(radians(32.113277))
* sin( radians(32.113391))));
但它根本没有改变有问题的结果!
PS:当然,我每次在重新创建之前都删除了该函数。还尝试将 return 类型从十进制更改为数字。
编辑:正如评论中所建议的,我也试过这个:
DELIMITER $
create function distance_meters()
returns decimal(8,6) DETERMINISTIC
begin
declare var_name decimal(8,6);
set var_name = ( 6371000 * acos( cos( radians(32.113277) ) * cos( radians( 32.113391 ) )
* cos( radians(34.801571) - radians(34.799259)) + sin(radians(32.113277))
* sin( radians(32.113391))));
return var_name;
end$
DELIMITER ;
select distance_meters()
我在这里错过了什么?
似乎解决方案分为两部分。一部分是函数中的错字,其中 lat1 和 lat2 被切换了。
return ( 6371000 * acos( cos( radians(lat1) ) * cos( radians( lat2
) ) * cos( radians(lng2) - radians(lng1)) + sin(radians(lat1)) * sin( radians(lat2))));
另一点是提高小数列的精度。我没有测试看需要的最小精度是多少,但是当我尝试使用 DECIMAL(18,6) 时它似乎有效。
我有一个基本查询,基于 this discussion 计算两个坐标之间的距离。 它似乎 运行 作为独立查询很好,但是当我尝试 运行 它作为存储函数时,它 return 奇怪的结果(通常为 null 或 99.9999...)。
独立查询是:
SELECT lat, lng,
( 6371 * acos( cos( radians(32.113277) ) * cos( radians( lat ) )
* cos( radians(lng) - radians(34.799259)) + sin(radians(32.113277))
* sin( radians(lat)))) AS distance_km,
( 6371000 * acos( cos( radians(32.113277) ) * cos( radians( lat ) )
* cos( radians(lng) - radians(34.799259)) + sin(radians(32.113277))
* sin( radians(lat)))) AS distance_meters
FROM (
SELECT 32.113391 as lat , 34.801571 as lng
) a
^ 这个 运行 没问题。然后我尝试将其更改为存储函数:
create function distance_meters(lat1 decimal(8,6), lng1 decimal(8,6), lat2 decimal(8,6), lng2 decimal(8,6) )
returns decimal(8,6) DETERMINISTIC
return ( 6371000 * acos( cos( radians(lat1) ) * cos( radians( lat2 ) )
* cos( radians(lng2) - radians(lng1)) + sin(radians(lat2))
* sin( radians(lat2))))
并像这样执行它:
select distance_meters(32.113277, 34.799259, 32.113391, 34.801571)
结果为 99.999999
我什至尝试将所有输入值(用于坐标)作为存储函数代码的一部分,如下所示:
create function distance_meters()
returns decimal(8,6) DETERMINISTIC
return ( 6371000 * acos( cos( radians(32.113277) ) * cos( radians( 32.113391 ) )
* cos( radians(34.801571) - radians(34.799259)) + sin(radians(32.113277))
* sin( radians(32.113391))));
但它根本没有改变有问题的结果!
PS:当然,我每次在重新创建之前都删除了该函数。还尝试将 return 类型从十进制更改为数字。
编辑:正如评论中所建议的,我也试过这个:
DELIMITER $
create function distance_meters()
returns decimal(8,6) DETERMINISTIC
begin
declare var_name decimal(8,6);
set var_name = ( 6371000 * acos( cos( radians(32.113277) ) * cos( radians( 32.113391 ) )
* cos( radians(34.801571) - radians(34.799259)) + sin(radians(32.113277))
* sin( radians(32.113391))));
return var_name;
end$
DELIMITER ;
select distance_meters()
我在这里错过了什么?
似乎解决方案分为两部分。一部分是函数中的错字,其中 lat1 和 lat2 被切换了。
return ( 6371000 * acos( cos( radians(lat1) ) * cos( radians( lat2 ) ) * cos( radians(lng2) - radians(lng1)) + sin(radians(lat1)) * sin( radians(lat2))));
另一点是提高小数列的精度。我没有测试看需要的最小精度是多少,但是当我尝试使用 DECIMAL(18,6) 时它似乎有效。