Cursores são áreas compostas de linhas e colunas armazenadas em memória que servem para armazenar o resultado de uma seleção que retorna nenhuma, uma ou diversas linhas. Os cursores, no banco de dados Oracle podem ser explícitos e implícitos, mas no momento irei abordar somente os cursores explícitos. Com o uso de cursores é possível selecionar um conjunto de linhas e manipular o resultado desta consulta linha a linha, dentro de um código PL/SQL (Program Language SQL), como stored procedures, triggers e código escritos dentro de ferramentas Oracle como o Developer, Designer ou Discoverer.

O cursor deve ser declarado na cláusula DECLARE de um código PL/SQL:


CURSOR nome_do_cursor (Relação_de_Parâmetros) IS
SELECT ...
[FOR UPDATE OF colunas]

Relação_de_Parâmetros pode ter o seguinte formato:


Nome_do_Parametro tipo_de_dado {:= / DEFAULT} valor_inicial

Após sua declaração, os cursores podem ser manipulados de forma extensa ou de forma resumida. Quando se utiliza a forma extensa, que é menos recomendada, os seguintes comandos são utilizados em combinação com uma estrutura de looping:

  • OPEN — abre o cursor, executando a consulta (comando SELECT) relacionada ao cursor, preenchendo parte de uma área de memória conhecida como private SQL area. Nesse momento, o ponteiro do cursor estará indicando o primeiro dos registros resultantes da consulta. A partir de então, para acessar dados desse cursor, o banco não será novamente acessado, pois todos os registros estarão disponíveis em memória após a execução do comando OPEN. Caso o cursor receba parâmetros é neste momento que os mesmos serão repassados.
  • FETCH — disponibiliza a linha corrente do cursor para as variáveis correspondentes e posiciona o ponteiro na próxima linha do cursor. As linhas armazenadas no cursor somente poderão ser processadas quando seu conteúdo for transferido para variáveis que possam ser manipuladas no PL/SQL.
  • CLOSE — fecha o cursor. Após sua manipulação, o cursor deve ser fechado com o comando CLOSE, para que a área de memória ocupada pelo resultado da consulta gerado por ele seja liberada.

Na forma reduzida, por sua vez, os comandos anteriores são substituídos pelo comando FOR unicamente:

  • FOR — controla de modo completo a acesso ao cursor, substituindo os três comandos anteriores, executando, automaticamente as seguintes ações:
    • cria a variável (do tipo registro) que irá receber os dados. Essa variável não deverá ser explicitamente declarada (DECLARE);
    • abre o cursor;
    • realiza a cópia das linhas uma a uma (FETCH), a cada iteração do comando;
    • controla o final do cursor, e
    • fecha o cursor.

A cada iteração do loop o ponteiro vai avançar pelos registros selecionados, começando sempre pelo primeiro, no qual estará posicionado na primeira iteração do comando FOR.

A seguir apresento um exemplo e a estrutura comparativa entre as duas formas de se trabalhar com cursores.



Declare
      Cursor Cur_Cli Is
      Select cd_cliente, nm_cliente
      From Cliente;
      Reg_Cli Cur_Cli%Rowtype;
Begin
      Open Cur_Cli;
      Loop
            Fetch Cur_Cli
            Into Reg_Cli;
            Exit When
                      Cur_Cli%NotFound;
            Dbms_Output.Put_Line
                      (Reg_Cli.nm_cliente);
      End Loop;
      Close Cur_Cli;
End;
Listagem 1. Exemplo Extenso

Declare
      Cursor Cur_Cli Is
      Select cd_cliente, nm_cliente
      From Cliente;
Begin
      For Reg_Cli in Cur_Cli
      Loop
            Dbms_Output.Put_Line
                        (Reg_Cli.nm_cliente);
      End Loop;
End;
Listagem 2. Exemplo Resumido

Abaixo é possível ver a comparação entre o uso de uma estrutura expandida e uma simplificada. Repare na forma expandida, as linhas em vermelho que são suprimidas ao optar-se pela forma simplificada utilizando o comando FOR.

Confira também