Se você está iniciando no mundo do PL/SQL, a linguagem de programação usada em conjunto com o Oracle Database, é provável que já tenha ouvido falar de cursores. Embora possam parecer complicados à primeira vista, cursores são ferramentas essenciais para manipular e processar resultados de consultas SQL que retornam múltiplas linhas. Neste artigo, vamos explorar em detalhes o que são cursores, como funcionam e quando utilizá-los, com exemplos claros e práticos.
O que é um Cursor?
Um cursor é um ponteiro que permite ao PL/SQL acessar e manipular os dados retornados por uma consulta SQL. Ele funciona como um mecanismo para processar linha por linha os resultados de uma consulta, dando maior controle sobre como os dados são utilizados em um programa.
Imagine que você executa uma consulta que retorna centenas de linhas. Como o PL/SQL não consegue trabalhar com todas essas linhas ao mesmo tempo, ele usa um cursor para percorrer os resultados uma linha por vez. Isso é especialmente útil quando é necessário aplicar lógica ou processamento específico em cada linha do conjunto de dados.
Tipos de Cursores em PL/SQL
Os cursores no PL/SQL podem ser classificados em dois tipos principais:
1. Cursor Implícito
Os cursores implícitos são criados e gerenciados automaticamente pelo Oracle sempre que você executa uma consulta SQL que não retorna múltiplas linhas, como:
- INSERT
- UPDATE
- DELETE
- SELECT INTO (desde que retorne uma única linha)
Você não precisa abrir, buscar ou fechar manualmente um cursor implícito. Ele é usado principalmente para consultas simples e operações em lote.
Exemplo de Cursor Implícito:
DECLARE
total_salarios NUMBER;
BEGIN
SELECT SUM(salario) INTO total_salarios FROM funcionarios;
DBMS_OUTPUT.PUT_LINE('Total de salários: ' || total_salarios);
END;
Neste exemplo, o Oracle cria um cursor implícito para executar a consulta SELECT SUM(salario)
e armazenar o resultado na variável total_salarios
.
2. Cursor Explícito
Os cursores explícitos são declarados e manipulados manualmente pelo programador. Eles são usados quando:
- A consulta retorna múltiplas linhas.
- É necessário maior controle sobre como os dados são processados.
Com um cursor explícito, você precisa seguir as seguintes etapas:
Etapas de um Cursor Explícito:
- Declarar o cursor e especificar a consulta SQL.
- Abrir o cursor para executar a consulta.
- Buscar (Fetch) os dados linha por linha.
- Fechar o cursor para liberar recursos.
Exemplo de Cursor Explícito:
DECLARE
CURSOR cur_funcionarios IS
SELECT nome, salario FROM funcionarios WHERE departamento_id = 10;
v_nome funcionarios.nome%TYPE;
v_salario funcionarios.salario%TYPE;
BEGIN
-- Abrir o cursor
OPEN cur_funcionarios;
-- Processar as linhas do cursor
LOOP
FETCH cur_funcionarios INTO v_nome, v_salario;
EXIT WHEN cur_funcionarios%NOTFOUND; -- Sai do loop quando não houver mais linhas
DBMS_OUTPUT.PUT_LINE('Nome: ' || v_nome || ', Salário: ' || v_salario);
END LOOP;
-- Fechar o cursor
CLOSE cur_funcionarios;
END;
Neste exemplo:
- Declaramos o cursor
cur_funcionarios
, que selecionanome
esalario
dos funcionários de um departamento específico. - Abrimos o cursor com
OPEN
. - Usamos
FETCH
para obter os dados linha por linha. - Fechamos o cursor com
CLOSE
ao finalizar o processamento.
Atributos de Cursor
Os cursores têm atributos especiais que ajudam a monitorar seu estado e comportamento. Esses atributos incluem:
- %FOUND: Retorna
TRUE
se uma linha foi retornada no últimoFETCH
. - %NOTFOUND: Retorna
TRUE
se nenhuma linha foi retornada no últimoFETCH
. - %ROWCOUNT: Retorna o número de linhas recuperadas até o momento.
- %ISOPEN: Retorna
TRUE
se o cursor está aberto.
Exemplo de Uso de Atributos:
IF cur_funcionarios%ISOPEN THEN
DBMS_OUTPUT.PUT_LINE('O cursor está aberto.');
END IF;
Quando Usar Cursores?
Os cursores são úteis em situações como:
- Processamento linha por linha de grandes conjuntos de resultados.
- Aplicação de lógicas complexas em cada linha retornada por uma consulta.
- Geração de relatórios ou logs com base em consultas dinâmicas.
Limitações e Alternativas
Embora os cursores sejam poderosos, eles podem ser ineficientes para grandes conjuntos de dados, pois processam linha por linha, o que pode impactar o desempenho. Em muitos casos, é melhor usar:
- Operações SQL em lote: Sempre que possível, deixe o SQL fazer o trabalho pesado.
- BULK COLLECT e FORALL: Para carregar grandes volumes de dados em uma única operação e aplicar lógica rapidamente.
Exemplo com BULK COLLECT:
DECLARE
TYPE t_salarios IS TABLE OF funcionarios.salario%TYPE;
v_salarios t_salarios;
BEGIN
SELECT salario BULK COLLECT INTO v_salarios FROM funcionarios WHERE departamento_id = 10;
FOR i IN v_salarios.FIRST .. v_salarios.LAST LOOP
DBMS_OUTPUT.PUT_LINE('Salário: ' || v_salarios(i));
END LOOP;
END;
Conclusão
Os cursores em PL/SQL são uma ferramenta essencial para manipular conjuntos de dados retornados por consultas SQL. Eles permitem maior controle e flexibilidade no processamento de dados linha por linha, sendo particularmente úteis para aplicações com lógicas de negócio complexas.
Porém, seu uso deve ser avaliado com cuidado em cenários onde o desempenho é crítico, buscando alternativas como o uso de BULK COLLECT ou operações SQL em lote.
Com o conhecimento adquirido aqui, você está pronto para utilizar cursores de forma eficiente e profissional em seus projetos PL/SQL! Se ficou com dúvidas ou quer saber mais, deixe um comentário e compartilhe este artigo com outros programadores!