2017-01-13 14 views
4

У меня есть базовый запрос с некоторыми вычислениями для расстояния между двумя координатами на основе this discussion. Кажется, что он отлично работает как автономный запрос, но когда я пытаюсь запустить его как хранимую функцию, он возвращает странные результаты (обычно 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: Конечно, я каждый раз отказывался от функции, прежде чем воссоздавать ее. Также попытался изменить тип возвращаемого значения с десятичной на числовую.

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, в нем DECLARE десятичную переменную, установите его в результат запроса и верните это. Любое изменение? – Mihai

+0

@Mihai спасибо, но, к сожалению, это не помогло - посмотрите обновленную (нижнюю часть) версию вопроса –

+1

Что произойдет, если вы увеличите десятичную точность. Можете ли вы попробовать (18,6)? –

ответ

1

Кажется, что в решении было две части. Одна часть была опечаткой в ​​функции, где lat1 и lat2 были переключены.

возврата (6371000 * ACOS (Cos (радианы (LAT1)) * Cos (радианы (LAT2 )) * Cos (радианы (lng2) - радиан (lng1)) + sin (радианы (LAT1)) * sin (радианы (lat2))));

Другой бит увеличил точность десятичной колонки. Я не тестировал, что нужно для минимальной точности, но когда я попытался с DECIMAL (18,6), он, похоже, работал.

+0

Вы правы, я, наверное, перепутал это поле! Но это не решает - ваша версия по-прежнему возвращает тот же неправильный ответ. Дело в том, что, как я сказал в исходном вопросе, даже когда я запускал его с жестко закодированными значениями, он все равно возвращал бы другой результат, когда он является хранимой функцией и когда это простой запрос. –

+0

комментарий после редактирования: (9,6) было достаточно для этого конкретного случая, но теперь я получил точку :) Спасибо! –

 Смежные вопросы

  • Нет связанных вопросов^_^