0

I got the error message while running Oracle PL/SQL recursive function

function returned without value

Anyone knows what might be the issue?

Here's my function

FUNCTION cgic (cnt IN NUMBER)
   RETURN VARCHAR2
   IS
      n_inv_code   VARCHAR2 (20);
      t_ic_chk                           NUMBER;
   BEGIN
                  SELECT DBMS_RANDOM.STRING ('X', 10)
      INTO n_inv_code
      FROM DUAL;

                  select count(*) into t_ic_chk from inv_code where inv_code = n_inv_code and rownum = 1;

      IF t_ic_chk = 1
      THEN
                    n_inv_code := cgic(cnt);
      ELSE
                    IF t_ic_chk = 0
                                THEN
                      RETURN n_inv_code;
                                END IF;
      END IF;
   END cgic;
7
  • What is going to happen when t_ic_chk <> 1 ? Commented Aug 23, 2016 at 18:44
  • with rownum = 1, should not it always be 0 or 1? Commented Aug 23, 2016 at 18:54
  • What's the full ORA code error, and did you get it during Compile time, or runtime ? Commented Aug 23, 2016 at 19:04
  • ORA-06503: PL/SQL: Function returned without value ORA-06512: at "ESAPP.EXPORT", line 24 ORA-06512: at "ESAPP.EXPORT", line 426 ORA-06512: at line 1 <br> The error is thrown at runtime when a shell script calling a SP which called this function. Line 24 is the declaration of the SP and line 426 is the function call. Commented Aug 24, 2016 at 0:45
  • Your function has an execution path that doesn't end to a return statement. It's simply a bug in the function implementation. Unfortunately the compiler won't catch the bug for your (at least in 11gR2) but the exception takes place in runtime only. Commented Aug 24, 2016 at 6:25

2 Answers 2

3

In the event t_ic_chk = 1

you assign the value of the recursive function back to the variable: n_inv_code

however, you don't DO anything with it. You probably want to return it.

I would recommend this code in your final section:

  IF t_ic_chk = 1
  THEN
                n_inv_code := cgic(cnt);
  END IF;
  RETURN n_inv_code;
END cgic;

That's all you need:

1) if you find a row, recurse back in until you can't find one, and return that value. 2) if you can't find a row, return that value back. 3) in the event you found a row, just hand-shake the value returned back to whoever called you.

Sign up to request clarification or add additional context in comments.

1 Comment

Oh yes. I forgot the return part here and expecting the recursive call return it .... Thx a lot!
0

The code starting with IF t_ic_chk = 1 might be replaced with

CASE t_ic_chk
  WHEN 0 THEN RETURN n_inv_code;
  WHEN 1 THEN RETURN cgic(cnt);
  ELSE RAISE_APPLICATION_ERROR(-20202, 'Unexpected t_ic_chk value=' || t_ic_chk);
END;

Done this way your function will either return an expected value or will raise an exception if it doesn't know what to do with the value it finds in t_ic_chk.

I do wonder why you're passing in the cnt parameter as it's never used in the procedure, except to pass it on in the recursive call.

Best of luck.

1 Comment

Thanks. I am actually calling this function in a loop within a SP and doesn't want to exit when there is an exception.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.