【问题标题】:MySQL stored function malfunctioning, but working as standalone queryMySQL 存储函数出现故障,但作为独立查询工作
【发布时间】:2017-01-13 16:26:34
【问题描述】:

我有一个基本查询,根据this discussion 计算两个坐标之间的距离。 它似乎作为独立查询运行良好,但是当我尝试将其作为存储函数运行时,它返回奇怪的结果(通常为 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:当然,我每次在重新创建之前都删除了该函数。还尝试将返回类型从十进制更改为数字。

编辑:按照 cmets 中的建议,我也试过这个:

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()

我在这里错过了什么?

【问题讨论】:

  • 这是一个在黑暗中的镜头,但使用 BEGIN END 部分,在其中 DECLARE 一个十进制变量,将其设置为查询结果并返回。有任何变化吗?
  • @Mihai 谢谢,但不幸的是这没有帮助 - 请参阅问题的更新(底部)版本
  • 如果增加小数精度会发生什么。你可以试试 (18,6) 吗?
  • @AldenW。这似乎解决了它,非常感谢!您可以将其发布为答案以便我接受吗?我应该注意到我需要 3+6 位的结果值,即 (9,6) 而不是 (8,6)。傻我
  • @YoavFeuerstein 啊,太好了。我已经更新了我的答案,包括关于小数精度的部分。

标签: mysql stored-procedures coordinates gis stored-functions


【解决方案1】:

似乎解决方案有两个部分。一部分是函数中的拼写错误,其中 lat1 和 lat2 被切换了。

return ( 6371000 * acos( cos( 弧度(lat1) ) * cos( 弧度( lat2 ) ) * cos( 弧度(lng2) - 弧度(lng1)) + sin(弧度(lat1)) * sin( 弧度(lat2))));

另一点是足够提高十进制列的精度。我没有测试以查看所需的最低精度是多少,但是当我尝试使用 DECIMAL(18,6) 时,它似乎可以工作。

【讨论】:

  • 你说得对,我可能把那个字段弄混了!但这并不能解决它 - 您的版本仍然返回相同的错误答案。问题是,正如我在原始问题中所说,即使我使用硬编码值运行它,当它是一个存储函数和一个简单查询时,它仍然会返回不同的结果。
  • 编辑后的评论:(9,6)对于这个特定的情况已经足够了,但现在我明白了:)谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-31
  • 2022-08-03
  • 2021-06-01
  • 2021-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多