ошибка postgresql - ОШИБКА: вход за пределы диапазона - PullRequest
2 голосов
/ 28 марта 2010

Функция ниже возвращает это сообщение об ошибке.Я подумал, что, возможно, именно это вызвало тип поля double_precision, и я попытался использовать CAST, но либо это не так, либо я сделал это неправильно ... Справка?

Вот ошибка:

ERROR:  input is out of range
CONTEXT:  PL/pgSQL function "calculate_distance" line 7 at RETURN

********** Error **********

ERROR: input is out of range
SQL state: 22003
Context: PL/pgSQL function "calculate_distance" line 7 at RETURN

А вот и функция:

 CREATE OR REPLACE FUNCTION calculate_distance(character varying, 
double precision, double precision, 
double precision, double precision)

      RETURNS double precision AS
    $BODY$ 
            DECLARE earth_radius double precision; 

            BEGIN 
                    earth_radius := 3959.0; 

                    RETURN earth_radius * acos(sin($2 / 57.2958) * 
sin($4 / 57.2958) + cos($2/ 57.2958) * cos($4 / 57.2958) 
* cos(($5 / 57.2958) - ($3 / 57.2958)));
            END; 
            $BODY$
      LANGUAGE 'plpgsql' VOLATILE
      COST 100;
    ALTER FUNCTION calculate_distance(character varying, 
double precision, double precision, double precision, 
double precision) OWNER TO postgres;



    //I tried changing (unsuccessfully) that RETURN line to: 

    RETURN CAST( (earth_radius * acos(sin($2 / 57.2958) 
* sin($4 / 57.2958) + cos($2/ 57.2958) * cos($4 / 57.2958) 
* cos(($5 / 57.2958) - ($3 / 57.2958))) ) AS text);

Ответы [ 6 ]

4 голосов
/ 04 апреля 2011

Немного поздно, но возникла та же проблема, и это происходит потому, что параметр acos находится за пределами [-1,1] (возможно, 1,01) перед вычислением ACOS вы должны использовать значение INTEGER

как это:


        RETURN  (earth_radius * acos(CAST ((sin($2 / 57.2958) 
sin($4 / 57.2958) + cos($2/ 57.2958) * cos($4 / 57.2958) 
 cos(($5 / 57.2958) - ($3 / 57.2958)) AS INTEGER)) );
3 голосов
/ 01 апреля 2015

Взгляните на это решение:

http://www.postgresql.org/message-id/12376732.post@talk.nabble.com

Проблема была в том, что ACOS () находился вне диапазона [-1,1], и это произошло потому, что он рассчитывал расстояние между LAT, LONG pair (то же место)

Я добавил WHERE L1.ID <> L2.ID, чтобы остановить рефлексивный расчет.

Мартейн ван Остерхоут писал:

В субботу, 18 августа 2007 г., 03:21:02 - 07:00, Дустов написал:

В моей базе данных только что появилась эта новая ошибка, и я понятия не имею, почему (потому что я преднамеренно не вносил никаких изменений в эту таблицу). У кого-нибудь есть идея, какой вход выходит за пределы диапазона или в чем проблема?

Единственная вещь в вашем запросе, которую я могу себе представить, это выход за пределы диапазона ACOS (), который должен быть между -1 и 1 (в противном случае результат было бы сложно).

Я бы попытался выяснить, каков аргумент ACOS, но, вероятно, какой-то угловой случай, когда вас округляет.

Надеюсь, это поможет,

У меня была такая же ошибка при расчете расстояния между координатами, но приведенный выше совет решил мою проблему.

1 голос
/ 14 марта 2019

Это связано с ошибкой округления с плавающей запятой, принимающей значение> 1.

Перед принятием ACOS ограничьте значение диапазоном от -1 до 1 с наименьшим и наибольшим

acos(least(greatest(...),-1),1));

Полная замена:

 CREATE OR REPLACE FUNCTION calculate_distance(character varying, 
double precision, double precision, 
double precision, double precision)

      RETURNS double precision AS
    $BODY$ 
            DECLARE earth_radius double precision; 

            BEGIN 
                    earth_radius := 3959.0; 

                    RETURN earth_radius *
acos(least(greatest(
    sin($2 / 57.2958) * 
    sin($4 / 57.2958) + cos($2/ 57.2958) * cos($4 / 57.2958) 
    * cos(($5 / 57.2958) - ($3 / 57.2958))
),-1),1));
            END; 
            $BODY$
      LANGUAGE 'plpgsql' VOLATILE
      COST 100;
    ALTER FUNCTION calculate_distance(character varying, 
double precision, double precision, double precision, 
double precision) OWNER TO postgres;
0 голосов
/ 23 октября 2018

Если координаты совпадают, вы получите исключение «[22003] ОШИБКА: вход за пределы диапазона». Чтобы предотвратить это, просто перехватите исключение и верните 0, например:

EXCEPTION
WHEN numeric_value_out_of_range
THEN RETURN 0;
0 голосов
/ 05 апреля 2011

У меня была такая же проблема, и я не мог установить модули contrib (я не был администратором).

Вы можете посмотреть здесь: http://en.wikipedia.org/wiki/Great-circle_distance

Численно устойчивая формула (для точек, не являющихся антиподами):

RETURN earth_radius * (2.*asin(sqrt((power(sin(radians(($4-$2)/2.)),2))+
(cos(radians($4))*cos(radians($2))*power(sin(radians(($5-$3)/2.)),2)))));

Если вам нужна универсальная формула, вы можете попытаться реализовать одну из atan2, которая описана на странице Википедии.

0 голосов
/ 28 марта 2010

А какой запрос вы выполняете, чтобы получить эту ошибку?

Вы смотрели на вклад? Имеет также функции для этих типов расчетов .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...