PL / SQL - Cursores
Neste capítulo, discutiremos os cursores em PL / SQL. O Oracle cria uma área de memória, conhecida como área de contexto, para processar uma instrução SQL, que contém todas as informações necessárias para processar a instrução; por exemplo, o número de linhas processadas, etc.
UMA cursoré um ponteiro para esta área de contexto. PL / SQL controla a área de contexto por meio de um cursor. Um cursor contém as linhas (uma ou mais) retornadas por uma instrução SQL. O conjunto de linhas que o cursor mantém é referido como oactive set.
Você pode nomear um cursor para que ele possa ser referido em um programa para buscar e processar as linhas retornadas pela instrução SQL, uma de cada vez. Existem dois tipos de cursores -
- Cursores implícitos
- Cursores explícitos
Cursores implícitos
Cursores implícitos são criados automaticamente pelo Oracle sempre que uma instrução SQL é executada, quando não há cursor explícito para a instrução. Os programadores não podem controlar os cursores implícitos e as informações nele contidas.
Sempre que uma instrução DML (INSERT, UPDATE e DELETE) é emitida, um cursor implícito é associado a essa instrução. Para operações INSERT, o cursor contém os dados que precisam ser inseridos. Para as operações UPDATE e DELETE, o cursor identifica as linhas que seriam afetadas.
No PL / SQL, você pode se referir ao cursor implícito mais recente como o SQL cursor, que sempre tem atributos como %FOUND, %ISOPEN, %NOTFOUND, e %ROWCOUNT. O cursor SQL tem atributos adicionais,%BULK_ROWCOUNT e %BULK_EXCEPTIONS, projetado para uso com o FORALLdeclaração. A tabela a seguir fornece a descrição dos atributos mais usados -
S.Não | Atributo e descrição |
---|---|
1 | %FOUND Retorna TRUE se uma instrução INSERT, UPDATE ou DELETE afetou uma ou mais linhas ou uma instrução SELECT INTO retornou uma ou mais linhas. Caso contrário, retorna FALSE. |
2 | %NOTFOUND O oposto lógico de% FOUND. Ele retorna TRUE se uma instrução INSERT, UPDATE ou DELETE não afetou nenhuma linha ou uma instrução SELECT INTO não retornou nenhuma linha. Caso contrário, retorna FALSE. |
3 | %ISOPEN Sempre retorna FALSE para cursores implícitos, porque o Oracle fecha o cursor SQL automaticamente após executar sua instrução SQL associada. |
4 | %ROWCOUNT Retorna o número de linhas afetadas por uma instrução INSERT, UPDATE ou DELETE, ou retornadas por uma instrução SELECT INTO. |
Qualquer atributo do cursor SQL será acessado como sql%attribute_name conforme mostrado abaixo no exemplo.
Exemplo
Estaremos usando a tabela CLIENTES que criamos e usamos nos capítulos anteriores.
Select * from customers;
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
+----+----------+-----+-----------+----------+
O programa a seguir atualizará a tabela e aumentará o salário de cada cliente em 500 e usará o SQL%ROWCOUNT atributo para determinar o número de linhas afetadas -
DECLARE
total_rows number(2);
BEGIN
UPDATE customers
SET salary = salary + 500;
IF sql%notfound THEN
dbms_output.put_line('no customers selected');
ELSIF sql%found THEN
total_rows := sql%rowcount;
dbms_output.put_line( total_rows || ' customers selected ');
END IF;
END;
/
Quando o código acima é executado no prompt SQL, ele produz o seguinte resultado -
6 customers selected
PL/SQL procedure successfully completed.
Se você verificar os registros na tabela de clientes, verá que as linhas foram atualizadas -
Select * from customers;
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2500.00 |
| 2 | Khilan | 25 | Delhi | 2000.00 |
| 3 | kaushik | 23 | Kota | 2500.00 |
| 4 | Chaitali | 25 | Mumbai | 7000.00 |
| 5 | Hardik | 27 | Bhopal | 9000.00 |
| 6 | Komal | 22 | MP | 5000.00 |
+----+----------+-----+-----------+----------+
Cursores explícitos
Cursores explícitos são cursores definidos pelo programador para obter mais controle sobre o context area. Um cursor explícito deve ser definido na seção de declaração do Bloco PL / SQL. Ele é criado em uma instrução SELECT que retorna mais de uma linha.
A sintaxe para criar um cursor explícito é -
CURSOR cursor_name IS select_statement;
Trabalhar com um cursor explícito inclui as seguintes etapas -
- Declarando o cursor para inicializar a memória
- Abrindo o cursor para alocar a memória
- Buscando o cursor para recuperar os dados
- Fechando o cursor para liberar a memória alocada
Declarando o Cursor
Declarar o cursor define o cursor com um nome e a instrução SELECT associada. Por exemplo -
CURSOR c_customers IS
SELECT id, name, address FROM customers;
Abrindo o Cursor
Abrir o cursor aloca a memória para o cursor e o torna pronto para buscar as linhas retornadas pela instrução SQL nele. Por exemplo, vamos abrir o cursor definido acima da seguinte maneira -
OPEN c_customers;
Buscando o Cursor
Buscar o cursor envolve acessar uma linha por vez. Por exemplo, vamos buscar linhas do cursor aberto acima da seguinte maneira -
FETCH c_customers INTO c_id, c_name, c_addr;
Fechando o Cursor
Fechar o cursor significa liberar a memória alocada. Por exemplo, fecharemos o cursor aberto acima da seguinte maneira -
CLOSE c_customers;
Exemplo
A seguir está um exemplo completo para ilustrar os conceitos de cursores explícitos & minua;
DECLARE
c_id customers.id%type;
c_name customer.name%type;
c_addr customers.address%type;
CURSOR c_customers is
SELECT id, name, address FROM customers;
BEGIN
OPEN c_customers;
LOOP
FETCH c_customers into c_id, c_name, c_addr;
EXIT WHEN c_customers%notfound;
dbms_output.put_line(c_id || ' ' || c_name || ' ' || c_addr);
END LOOP;
CLOSE c_customers;
END;
/
Quando o código acima é executado no prompt SQL, ele produz o seguinte resultado -
1 Ramesh Ahmedabad
2 Khilan Delhi
3 kaushik Kota
4 Chaitali Mumbai
5 Hardik Bhopal
6 Komal MP
PL/SQL procedure successfully completed.