views:

6012

answers:

9

Hi everyone,

I'm migrating a TSQL stored procedure to PL/SQL and have encountered a problem - the lack of a CONTINUE keyword in Oracle 10g.

I've read that Oracle 11g has this as a new feature, but upgrading is not an option unfortunately.

Is there any alternative to CONTINUE in 10g? I don't believe it's practical to restructure the logic of the SP as a work-around, because I have an outer loop, an IF, then a nested IF, then the CONTINUE at the end of a statement block within that IF.

Any help would be greatly appreciated, cheers.

+3  A: 

Can you refactor the IFs into a function, returning at the appropriate point (early if necessary). Then the control flow will pick up in the loop at the right place.

Does that make sense?

cagcowboy
+11  A: 

You can simulate a continue using goto and labels.

DECLARE
   done  BOOLEAN;
BEGIN
   FOR i IN 1..50 LOOP
      IF done THEN
         GOTO end_loop;
      END IF;
   <<end_loop>>  -- not allowed unless an executable statement follows
   NULL; -- add NULL statement to avoid error
   END LOOP;  -- raises an error without the previous NULL
END;
jop
+1 for an ugly workaround to handle an ugly statement :)
Nick Pierpoint
Sometimes, we just have to type it in and cover our noses afterwards. :)
jop
A: 

Jop, thanks. That's more or less what I had done myself, but didn't know the trick with the NULL after the label to stop the compilation error - good one.

Just as a point of interest, is there any way to do this that doesn't involve GOTO labels? I only ask because I'm not totally familiar with them and any potential side-effects they might have. I know they get a bad rep, but I think that they're probably appropriate in this situation, would that be correct?

CagCowboy, that's a neat idea, but unfortunately the logic of this SP is pretty complex and it would be more of a pain than anything to extract the IFs out like that.

C.McAtackney
I think in your case, the use of GOTO is acceptable. GOTOs get bad rep when people abuse it - resulting in spaghetti code. It is always better to refactor so you don't need to use it.
jop
A: 

In Oracle there is a similar statement called EXIT that either exits a loop or a function/procedure (if there is no loop to exit from). You can add a WHEN to check for some condition.

You could rewrite the above example as follows:

DECLARE
   done  BOOLEAN;
BEGIN
    FOR i IN 1..50 LOOP
     EXIT WHEN done;
   END LOOP;
END;

This may not be enough if you want to exit from deep down some nested loops and logic, but is a lot clearer than a couple of GOTOs and NULLs.

IronGoofy
A: 

The EXIT solution wouldn't really work in this case, because it would terminate the entire loop, as opposed to just start at the next iteration as CONTINUE would do.

I think I'll have to go with the GOTO solution, cheers everyone for your suggestions!

C.McAtackney
+2  A: 

It's not available in 10g, however it's a new feature in 11G

dt
A: 

Thanks Jop...

Yogesh N. Patil

A: 

Hi Guys ! Though it's a bit complex and just a fake, you can use exception this way :

DECLARE
  i NUMBER :=0;
  my_ex exception;
BEGIN
  FOR i IN 1..10
  LOOP
      BEGIN
         IF i = 5 THEN
            raise my_ex;
         END IF;
         DBMS_OUTPUT.PUT_LINE (i);
      EXCEPTION WHEN my_ex THEN
         NULL;
      END;
  END LOOP;

END;
+1  A: 

Not exactly elegant, but simple:

DECLARE
   done  BOOLEAN;
BEGIN
   FOR i IN 1..50 LOOP
      IF done THEN
         NULL;
      ELSE
         <do loop stuff>;
      END IF;
   END LOOP; 
END;
David Oneill