Как избежать ошибок в функциях тригонометрии в Oracle? - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть курсон в моей хранимой процедуре

 SELECT a.id, a.full_address, me.answer medid, me.name NAME, a.nlat, a.nlong, a.parent_table
      FROM   example_table_1 a,
             (SELECT pnradius         AS radius,
                     111.045          AS distance_unit,
                     57.2957795       AS rad2deg,
                     0.01745329251994 AS deg2rad
              FROM   dual) geo,
             example_table me
      WHERE  a.nlat BETWEEN pnlatitude - (geo.radius / geo.distance_unit) AND
             pnlatitude + (geo.radius / geo.distance_unit)
      AND    a.nlong BETWEEN pnlongitude - (geo.radius / (geo.distance_unit * cos(deg2rad * (pnlatitude)))) AND
             pnlongitude + (geo.radius / (geo.distance_unit * cos(deg2rad * (pnlatitude))))
      AND    geo.distance_unit * rad2deg *
             (acos(cos(deg2rad * (pnlatitude)) * cos(deg2rad * (a.nlat)) * cos(deg2rad * (pnlongitude - a.nlong)) +
                    sin(deg2rad * (pnlatitude)) * sin(deg2rad * (a.nlat)))) < pnradius
      AND    a.parent_id = me.answer
      AND    a.parent_table = 'example_table'

pnlatitude и pnlongiture - это параметры процедуры.В большинстве случаев этот курсор прекрасно работает.Но иногда в некоторых регионах России этот курсор вызывает эту ошибку:

enter image description here

Я понимаю, что здесь происходит, но я не могу отследить, где это происходитэто произошло.Я могу настроить значение deg2rad, и это помогает, но тогда эта ошибка появится с другими координатами.

Можно ли уменьшить значение параметра тригонометрической функции до 1, если оно больше 1?

1 Ответ

0 голосов
/ 20 февраля 2019

Используйте функцию LEAST, чтобы гарантировать, что вы не передадите аргумент больше 1 в ACOS:

SELECT a.id, a.full_address, me.answer medid, me.name NAME, a.nlat, a.nlong, a.parent_table
  FROM example_table_1 a,
       (SELECT pnradius         AS radius,
               111.045          AS distance_unit,
               57.2957795       AS rad2deg,
               0.01745329251994 AS deg2rad
          FROM dual) geo,
       example_table me
  WHERE a.nlat BETWEEN pnlatitude - (geo.radius / geo.distance_unit)
                   AND pnlatitude + (geo.radius / geo.distance_unit) 
    AND a.nlong BETWEEN pnlongitude - (geo.radius / (geo.distance_unit * cos(deg2rad * (pnlatitude))))
                    AND pnlongitude + (geo.radius / (geo.distance_unit * cos(deg2rad * (pnlatitude))))
    AND geo.distance_unit * rad2deg *
        (acos(LEAST(cos(deg2rad * (pnlatitude)) * cos(deg2rad * (a.nlat)) * cos(deg2rad * (pnlongitude - a.nlong)) +
        sin(deg2rad * (pnlatitude)) * sin(deg2rad * (a.nlat)), 1))) < pnradius
    AND a.parent_id = me.answer
    AND a.parent_table = 'example_table'

Это то же самое, что и ваш оригинал с добавлением LEAST(big-long-calc, 1) внутриACOS звонок.Надеюсь, я посчитал правильные скобки - если нет, отрегулируйте по мере необходимости.: -)

Удачи.

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