2016-10-18 11 views
1

오늘 다소 신비한 문제가 발생했습니다. I는 다음과 같은 파라미터들 (매개 변수들 중 하나가 0 인 경우 내에서 정의 예외를을 일으켜야) 내 SQL 함수 f_interestrate() 실행 같이SQL : 함수에서 예외 처리

ORA-06503: PL/SQL: Function returned without value
ORA-06512: at "NOAHBASE.GENERAL_FUNCTIONS", line 73
06503. 00000 - "PL/SQL: Function returned without value"
*Cause: A call to PL/SQL function completed, but no RETURN statement was executed.

*Action: Rewrite PL/SQL function, making sure that it always returns a value of a proper type.

:
SELECT GENERAL_FUNCTIONS.F_INTERESTRATE(2500000, 0.10, 0) FROM dual; 

날 다음 오류 준

하지만 다음 코드 샘플에서 볼 수 있듯이이 함수는 대신 정의 된 양식 ex_invalid_devisor을 발생시켜야합니다. 이 함수는 패키지 안에 중첩되어 있음을 언급하는 것을 잊지 마십시오.

FUNCTION f_interestrate(pn_principal NUMBER, pn_interest NUMBER, pn_years NUMBER) RETURN NUMBER IS 
     vn_interestrate NUMBER; 
     ex_invalid_devisor EXCEPTION; 
    BEGIN 
     IF pn_principal = 0 OR 
     pn_interest = 0 OR 
     pn_years = 0 THEN 
      RAISE ex_invalid_devisor; 
     ELSE 
     vn_interestrate := ((pn_interest/pn_principal)-1)/pn_years; 
     RETURN vn_interestrate; 
     END IF; 
    EXCEPTION 
     WHEN ex_invalid_devisor THEN 
     DBMS_OUTPUT.PUT_LINE('Devisor must be bigger then 0'); 
    END; 

뭐가 잘못 되었나요?

+3

는 예외가 발생했을 경우에는'return' 조항이 없다. 넣어야합니다. 예 : catch 블록에'return null '을 던지거나 예외를 다시 올리십시오. 현재 블록이 자동으로 블로킹합니다 –

+0

프로 시저가 예외를 발생시킨 다음 메시지를 인쇄하기 위해 오류를 처리하지만이 경우 반환 값이 없습니다 – Aleksej

+1

예, 예외 블록이 아무 것도하지 않습니다. 함수에서 오류를 발생시킬 필요가 있거나 사용자가 정의한 오류의 경우 RAISE_APPLICATION_ERROR를 사용하여 특정 오류 메시지를 출력하거나 값을 반환 할 수 있습니다. 또한 DBMS_OUTPUT을 사용해야하는 경우 디버깅 용도로만 사용해야합니다 (IMHO). 프로덕션 코드에는 아무 것도 없습니다. 개인적으로, 나는 디버깅의 다른 방법으로 갈 것입니다 - 만약 당신이 행동이 발생했는지 아닌지를 기록 할 필요가 있다면 왜 그것을 테이블에 기록하지 않을까요? – Boneist

답변

2

이렇게하면 처리해야합니다 ... 코드에 'return -1'을 추가했습니다. HTH. 기본 오류 메시지가 나타납니다 다음

create or replace function f_interestrate 
    (pn_principal number 
    , pn_interest number 
    , pn_years  number) 
    return number 
as 
begin 
    return ((pn_interest/pn_principal) - 1)/pn_years; 
end; 

: PL/SQL이 이미 완벽하게 좋은 zero_divide 예외가, I는 다음과 같이 단지 함수를 작성하도록 유혹 할 것입니다함에 따라

create or replace FUNCTION f_interestrate(pn_principal NUMBER, pn_interest NUMBER, pn_years NUMBER) RETURN NUMBER IS 
     vn_interestrate NUMBER; 
     ex_invalid_devisor EXCEPTION; 
    BEGIN 
     IF pn_principal = 0 OR 
     pn_interest = 0 OR 
     pn_years = 0 THEN 
      RAISE ex_invalid_devisor; 
     ELSE 
     vn_interestrate := ((pn_interest/pn_principal)-1)/pn_years; 
     RETURN vn_interestrate; 
     END IF; 
    EXCEPTION 
     WHEN ex_invalid_devisor THEN 
     DBMS_OUTPUT.PUT_LINE('Devisor must be bigger then 0'); 
     return -1; 
    END; 

SQL> select F_INTERESTRATE(2500000, 0.10, 0) FROM dual; 

F_INTERESTRATE(2500000,0.10,0) 
------------------------------ 
          -1 
+0

이것은 함수 호출자가 -1을 오류로 처리 할 준비가되어있는 경우에만 의미가 있습니다. 게다가 당신은 -1이 유효한 반환 값이 될 수 없다는 것을 확신해야합니다. – Aleksej

+0

그것은 문제를 지적하고 문제가 해결되었음을 증명하는 것입니다. 값 반환 값을 '-1'에서 언제든지 변경할 수 있습니다. 요점은 값을 반환하지 않고는 함수를 가질 수 없다는 것입니다. -1 또는 -x 값을 사용할 수없는 경우 제로 나눗셈 예외를 처리하지 않는 것이 가장 좋습니다. – pahariayogi

2

SQL> select f_interestrate(2500000, 0.10, 0) from dual; 
select f_interestrate(2500000, 0.10, 0) from dual 
     * 
ERROR at line 1: 
ORA-01476: divisor is equal to zero 
ORA-06512: at "XXX.F_INTERESTRATE", line 8 

또는 당신이 정말로 어떤 사용자 정의 처리를 필요로하는 경우,

create or replace function f_interestrate 
    (pn_principal number 
    , pn_interest number 
    , pn_years  number) 
    return number 
as 
begin 
    return ((pn_interest/pn_principal) - 1)/pn_years; 
exception 
    when zero_divide then 
     [[[ do something here ]]] 
end; 

pn_interest이 제수 일 때도 사용자 정의 ex_invalid_devisor 예외를 발생시키는 것으로 나타났습니다. 제수로 사용되지는 않았지만 여기에 누락 된 일부 미묘한 논리가있을 수 있습니다.

(편집 :. pn_interest가 0 어쩌면 당신은 단지에 관계없이 pn_principal을 반환해야 할 경우, 그것에 대해 생각)