如何避免Oracle中的三角函数出错?

时间:2019-02-20 12:11:51

标签: oracle plsql

我的存储过程中有一个诅咒

 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 :(得分:2)

使用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。希望我算对了括号-如果没有,请根据需要进行调整。 :-)

好运。