Domanda

Sto migrando una procedura memorizzata TSQL su PL / SQL e ho riscontrato un problema: la mancanza di una parola chiave CONTINUE in Oracle 10g.

Ho letto che Oracle 11g ha questa come una nuova funzionalità, ma purtroppo l'aggiornamento non è un'opzione.

C'è qualche alternativa a CONTINUA in 10g? Non credo sia pratico ristrutturare la logica dell'SP come soluzione, perché ho un loop esterno, un IF, quindi un IF nidificato, quindi il CONTINUE alla fine di un blocco di istruzioni all'interno di tale IF.

Qualsiasi aiuto sarebbe molto apprezzato, evviva.

È stato utile?

Soluzione

Puoi simulare un proseguimento usando goto e etichette .

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;

Altri suggerimenti

Sebbene sia un po 'complesso e solo un falso, puoi usare l'eccezione in questo modo:

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;

In effetti, PL SQL ha qualcosa da sostituire CONTINUA. Tutto quello che devi fare è aggiungere un'etichetta (un nome) al loop:

declare
   i integer;
begin
   i := 0;

   <<My_Small_Loop>>loop

      i := i + 1;
      if i <= 3 then goto My_Small_Loop; end if; -- => means continue

      exit;

   end loop;
end;

Per ricerche future, nell'oracolo 11g hanno aggiunto un'istruzione continue , che può essere utilizzata in questo modo:

    SQL> BEGIN
  2     FOR i IN 1 .. 5 LOOP
  3        IF i IN (2,4) THEN
  4           CONTINUE;
  5        END IF;
  6        DBMS_OUTPUT.PUT_LINE('Reached on line ' || TO_CHAR(i));
  7     END LOOP;
  8  END;
  9  /
Reached on line 1
Reached on line 3
Reached on line 5

PL/SQL procedure successfully completed.

Non è disponibile in 10g, tuttavia è una nuova funzionalità in 11G

Riesci a trasformare gli IF in una funzione, ritornando al punto appropriato (presto se necessario). Quindi il flusso di controllo riprenderà nel loop nel posto giusto.

Ha senso?

Non esattamente elegante, ma semplice:

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

In Oracle esiste un'affermazione simile chiamata EXIT che esce da un ciclo o da una funzione / procedura (se non esiste un ciclo da cui uscire). Puoi aggiungere QUANDO per verificare la presenza di alcune condizioni.

Potresti riscrivere l'esempio sopra come segue:

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

Questo potrebbe non essere sufficiente se vuoi uscire dal profondo di alcuni loop e logiche annidate, ma è molto più chiaro di un paio di GOTO e NULL.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top