postgresql错误 - 错误:输入超出范围

时间:2010-03-28 15:19:42

标签: postgresql function

以下函数会一直返回此错误消息。我认为也许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 个答案:

答案 0 :(得分:4)

稍晚但有同样的问题,因为acos param在[-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)) );

答案 1 :(得分:3)

看看这个解决方案:

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

  

问题确实是ACOS()在[-1,1]范围之外,并且   发生这种情况是因为它正在计算相同的距离   LAT,LONG对(同一地点)

     

我添加了WHERE L1.ID<> L2.ID停止反身计算。

     

Martijn van Oosterhout写道:

     
    

2007年8月18日星期六下午03:21:02 -0700,dustov写道:

         
      

我的数据库刚出现这个新错误,我不明白为什么(因为我       没有故意对此表做出任何更改)。有谁有       一个       想法哪个输入超出范围 - 或者问题可能是什么?

    
         

我可以想象你的查询中唯一超出范围的是     ACOS()需要在-1和1之间(否则结果     会很复杂。)

         

我试着看看ACOS的论点是什么,但可能是这样     一些角落的情况,四舍五入让你。

         

希望这有帮助,

  

我在计算坐标之间的距离时遇到了同样的错误,但上面的提示解决了我的问题。

答案 2 :(得分:1)

这是由于浮点舍入错误导致该值取> 1。

在使用ACOS之前,请用least and greatest将值限制在-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;

答案 3 :(得分:0)

我遇到了同样的问题,我无法安装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之一。

答案 4 :(得分:0)

如果坐标相同,则会出现异常“ [22003]错误:输入超出范围”。为了防止这种情况,只需捕获异常并返回0,如下所示:

EXCEPTION
WHEN numeric_value_out_of_range
THEN RETURN 0;

答案 5 :(得分:-2)

你执行什么查询来获得此错误?

你看过contrib了吗?还有这些类型calculations的函数。