2017-01-13 16 views
4

this discussionに基づいて、2つの座標間の距離の計算に関する基本的なクエリがあります。 スタンドアロンのクエリとしてはうまく動作するようですが、ストアド関数として実行しようとすると、奇妙な結果(通常はnullまたは99.9999 ...)が返されます。MySQLストアド機能が正常に機能していませんが、スタンドアロンクエリとして動作します

スタンドアロンのクエリは次のとおりです。

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:もちろん、私はその機能を再作成する前に毎回削除しました。また、戻り値の型を10進数から数値に変更しようとしました。

EDIT:コメントで提案されているように、私もこの試みた:

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

を、私はここで何をしないのですか?

+0

暗闇の中で撮影しますが、BEGIN ENDセクションを使用して、10進変数を宣言し、照会結果にSETして返します。変更はありますか? – Mihai

+0

@Mihaiありがとうございます。残念ながら助けにならなかった - 質問の更新された(下部)バージョンをご覧ください。 –

+1

小数点精度を上げるとどうなりますか?あなたは(18,6)を試すことができますか? –

答えて

1

解決策に2つの部分があるようです。 1つの部分は関数のtypoで、lat1とlat2が切り替えられました。

リターン(6371000の* ACOS(COS(ラジアン(LAT1))* COS(ラジアン(LAT2 ))* COS(ラジアン(lng2) - ラジアン(lng1))+罪(ラジアン(LAT1) )* sin(ラジアン(lat2))));

もう1つのビットは、十進数列の精度を十分に向上させました。私は必要な最小精度が何であるかを調べるためにテストしませんでしたが、DECIMAL(18,6)を試してみるとうまくいくように見えました。

+0

あなたはそうです、私はおそらくそのフィールドを混ぜ合わせました!しかし、それはそれを解決しません - あなたのバージョンはまだ同じ間違った答えを返します。問題は、元の質問で述べたように、ハードコードされた値で実行した場合でも、ストアドファンクションのときと単純なクエリのときとでは異なる結果を返すことになります。 –

+0

編集後のコメント:この特定のケースでは(9,6)は十分でしたが、今はポイントがあります:)ありがとう! –

関連する問題