함수가 NULL을 되돌리고 있습니다. 0 2 1,601

by 김선우 [SQL Query] PostgreSQL Function [2018.01.18 20:36:46]


안녕하세요

거리를 구하는 함수에서 EXCEPTION이 발생하고 있습니다.

CREATE OR REPLACE FUNCTION latlon_to_dist(lat1 float,lon1 float,lat2 float,lon2 float) RETURNS float AS $$

DECLARE dist float;
BEGIN
dist := ROUND((6378.137*acos(cos(radians(lat1))*cos(radians(lat2))*cos(radians(lon2)-radians(lon1))+sin(radians(lat1))*sin(radians(lat2))))::NUMERIC*1000,0);

RETURN dist;
END;
$$ LANGUAGE plpgsql;

상기 함수를 다음과 같이 실행하면

select latlon_to_dist(35.664261,139.5797779,35.664261,139.5797778)

에러가 발생하고 에러메세지는 22003:input is out of range 과 같이 출력됩니다.

에러를 없애는 방법과 dist가 NULL이 된다면 강제로 0을 설정해서 되돌리는 방법을 알고 싶습니다.

 

감사합니다.

 

by 마농 [2018.01.18 21:23:23]

계산식을 조금씩 나누어 수행해 보니 acos 에서 에러가 나네요.
acos 안에만 실행해 보면 1이 나오네요.
acos(1) 을 해보면 에러 안나네요.
1로 보이지만 실제로는 1이 아닌 1.00000000000000001 정도가 계산되어 나온게 아닐까? 추측됩니다.
소수점에서 미세한 오차 발생
acos(1.0000000001) 해보니 동일한 오류 발생됩니다.
1보다 클 경우 1을 반환하도록 LEAST 함수 추가했습니다.
 

SELECT ROUND((6378.137 *
       acos(    -- 여기서 에러
       LEAST(1, -- 추가
       cos(radians(lat1))*cos(radians(lat2))*cos(radians(lon2)-radians(lon1))+sin(radians(lat1))*sin(radians(lat2))
       )        -- 추가
       )
       )::NUMERIC*1000
       ,0)
  FROM (SELECT  35.664261 ::float lat1
             , 139.5797779::float lon1
             ,  35.664261 ::float lat2
             , 139.5797778::float lon2
        ) a
;

 


by 김선우 [2018.01.19 09:40:55]

마농님 매번 감사드립니다.

문제 해결 되었습니다.

 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입