Pular para o conteúdo

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

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 exceçã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

Sergio Willians

Sergio Willians

Sergio Willians é o fundador do GPO (Grupo de Profissionais Oracle) e possui quase 30 anos de experiência em tecnologias Oracle, sendo especialista em desenvolvimento Forms/Reports, PL/SQL e EBS (E-Business Suite) nos módulos Receivables, Payables e General Ledger. Atualmente trabalha na Scania Latin America, onde se dedica à área de integração de dados com Confluent Kafka. Sua paixão é compartilhar conhecimento com a comunidade Oracle, contribuindo para o crescimento e a excelência da plataforma.

Comentário(s) da Comunidade

  1. Avatar de Sergio Willians

    Opa, eae Denis !

    Então, tudo depende de uma análise de caso a caso. Porém, vou te dar uma resposta em um contexto amplo.

    Eu enxergo 2 casos pelo menos:
    1) No cursor explicíto você pode varrre mais de uma vez o conjunto de dados. Pois ele só será fechado quando você o fizer;
    2) Reutilização do cursor em diversas partes diferente do código.

    Como eu disse, o ideal é avaliar caso a caso. Mas posso afirmar que em alguns desses casos, os pontos que citei acima são realmente uma baita vantagem.

Deixe um comentário

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

plugins premium WordPress