GPO ( Grupo de Profissionais Oracle )
A maior comunidade Oracle do Brasil !

Cursor Explícito ou Implícito ? Qual o melhor ?

Olá pessoal !

Se você tem alguma dúvida sobre usar cursor explícito ou implicíto, hoje eu apresentarei 1 motivo para usar sempre o implícito. Não utilizarei nenhum argumento do tipo ‘código mais limpo’ ou ‘performance com BULK’. Apenas a abertura e fechamento de cursores !

No cursor explícito, a abertura e fechamento de cursores deve ser controlada. O problema é que muitos desenvolvedores acabam não codificando bem a parte lógica,  esquecendo um pouco das exceções. Veja o exemplo abaixo:

DECLARE
   vNUM   NUMBER;
   CURSOR c1 IS
      SELECT * FROM dual;

   r1 c1%ROWTYPE;

BEGIN
   OPEN c1;
   LOOP
      FETCH c1 INTO r1;
      -- Forçando exceção
      vNUM := 'X';
   EXIT WHEN c1%NOTFOUND;   
   END LOOP;

   CLOSE c1;

EXCEPTION
   WHEN OTHERS THEN
      IF c1%ISOPEN THEN
            DBMS_OUTPUT.PUT_LINE('Cursor Aberto !');
      ELSE   
            DBMS_OUTPUT.PUT_LINE('Cursor Fechado !');

      END IF;

END;

Resultado
----------------------
1 Cursor Aberto !

Veja que o cursor ficou aberto ao estourar exceção. Isso se resolve facilmente, alterando o código na exception e fechando o cursor.

EXCEPTION
   WHEN OTHERS THEN
      IF c1%ISOPEN THEN
         DBMS_OUTPUT.PUT_LINE('Cursor Aberto !');
         CLOSE c1;
 
        IF NOT c1%ISOPEN THEN
           DBMS_OUTPUT.PUT_LINE('Cursor Fechado !');

        END IF;

      ELSE   
            DBMS_OUTPUT.PUT_LINE('Cursor Fechado !');

      END IF;

END;

Resultado
----------------------
1 Cursor Aberto !
2 Cursor Fechado !

Executemos o mesmo script, mas utilizando cursor implícito:

DECLARE
   vNUM  NUMBER;
   CURSOR c1 IS
      SELECT * FROM dual;
   r1 c1%ROWTYPE;

BEGIN
   FOR r1 IN c1
   LOOP
      -- Forçar Exception
      vNUM := 'X';
    
   END LOOP;

EXCEPTION
   WHEN OTHERS THEN
      IF c1%ISOPEN THEN
         DBMS_OUTPUT.PUT_LINE('Cursor Aberto !');
      ELSE   
         DBMS_OUTPUT.PUT_LINE('Cursor Fechado !');

      END IF;
    
END;

Resultado
----------------------
1 Cursor Fechado !

Não entrarei no mérito de que cursores são fechados automaticamente, após o término de um bloco anônimo. Pense no contexto de uso dentro de Packages e procedures, onde é necessário o fechamento dos cursores ao se utilizar um cursor explicíto.

Perceba que utilizando FOR o cursor é automáticamente fechado, após o estouro da execeção ! Essa é uma vantagem na utilização de cursores implicítos !

Sobre qual é o melhor ? Tire suas próprias conclusões com as informações acima ! 😛

Bom pessoal, espero que essa informação ajude !

Um grande abraço

Share

You may also like...

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *