You are on page 1of 5

O que um Cursor?

Um cursor representa uma tabela temporariamente armazenada em memria. Quando uma consulta retorna mltiplas linhas, necessrio declarar um "CURSOR" para process-las. Um cursor similar a uma varivel de arquivo ou um ponteiro de arquivo, que aponta para uma nica linha (tupla) do resultado da consulta. Em SQL os cursores so controlados por trs comandos: OPEN, FETCH, CLOSE. O cursor iniciado com o comando OPEN, que executa a consulta, devolve o conjunto resultante de linhas e coloca o cursor para a posio anterior primeira linha do resultado da consulta. O comando FETCH, quando executado pela primeira vez, devolve a primeira linha nas variveis do programa e coloca o cursor para apontar para aquela linha. Subseqentes execues do comando FETCH avanam o cursor para a prxima linha no conjunto resultante e retornam a linha nas variveis do programa. Quando a ltima linha processada, o cursor desbloqueado com o comando CLOSE. Os cursores existem principalmente para que linguagens de programao que no permitem abstrao para conjunto de registros, como C, possam receber as linhas da resposta de uma consulta SQL uma de cada vez. Com a utilizao de "CURSORES", apresentam-se esses dados como resultados das consulta, atravs de itens que representam os elementos de interface com o usurio, atendendo os preceitos impostos pelos diferentes paradigmas possivelmente envolvidos. Com isso os resultados so mostrados utilizando o objeto padro da interface, disponveis nas ferramentas de construo de interfaces. Dessa forma, o ciclo de busca de informao nos mais variados servidores tem incio e fim na interface com o usurio. Quando voc executa uma instruo SQL no Oracle, o PL/SQL criou uma rea de trabalho privada para a instruo chamada PGA. onde os dados que so retornados da instruo SQL so armazenados. O nome do cursor basicamente um apontador para esta rea. Agora criaremos um cursor: CURSOR c_customers is SELECT * from CUSTOMERS; Podemos abrir o cursor: OPEN c_customers; Podemos selecionar dados do cursor: FETCH c_customers into customers_rec; E podemos fechar o cursor. CLOSE c_customers; Quando selecionamos dados de um cursor estamos na verdade selecionando dados de uma tabela virtual definida pela definio do cursor. Cursores implcitos e explcitos Vamos passar por este assunto brevemente. Toda instruo SQL que voc execute um cursor implcito. Um cursor explcito aquele que criamos acima. Se voc d um nome ao cursor ento ele um cursor explcito. Em seu PL/SQL sempre use cursores explcitos. Declarando cursores Antes que voc possa usar seu cursor explcito, voc deve primeiro declar-lo. H trs formas diferentes para se declarar cursores explcitos: DECLARE cursor c_customers IS SELECT name, phone FROM customers; DECLARE cursor c_customers(i_cust_id In NUMBER) IS SELECT name, phone FROM customers

WHERE cust_id = i_cust_id; DECLARE cursor c_customers RETURN customers%ROWTYPE IS SELECT name, phone FROM customers; A segunda forma criou o cursor com a varivel passada como um argumento. A terceira forma raramente usada.

Abrindo cursores Quando voc abre um cursor, o PL/SQL executa a consulta para aquele cursor. A instruo open no retorna qualquer dado, isto feito pela instruo fetch. O SGBDR Oracle garante consistncia de leitura para o cursor. Todos os dados buscados no so afetados por outras atualizaes, inseres ou excluses efetuadas sobre a(s) tabela(s) no cursor. Um cursor no pode ser aberto duas vezes, ele deve ser fechado primeiro ou o Oracle retornar um erro. um bom hbito checar se o cursor est aberto antes de abri-lo. Isto pode ser feito usando o atributo %ISOPEN: if c_customers%ISOPEN then close c_customers; end if; open c_customers; Buscando dados do cursor O motivo de declarar um cursor para buscar, ou retornar, as linhas de dados do cursor e manipular os dados de alguma forma. Voc deve trazer os dados para dentro de uma varivel do tipo que est sendo trazido. Com o nosso cursor c_customers que abrimos ns precisamos ter duas variveis para colocar os dados nelas. O formato da instruo fetch : FETCH c_customers INTO l_name, l_phone; O nmero de variveis deve ser o mesmo da declarao do cursor. Sempre tome a precauo de usar declaraes de variveis ancoradas. Lembre do captulo 4. Agora como sabemos quando j trouxemos todas as linhas definidas pelo cursor? Usamos o atributo %NOTFOUND do cursor. Ele verdadeiro quando no existem mais registros no conjunto ativo. Fechando cursores Quando voc tiver terminado o trabalho com o cursor sempre bom fech-lo, cada cursor usa memria, ento fech-lo permite que o Oracle recupere esta memria: Select for Update com Cursores Quando voc efetua uma instruo select no Oracle, nenhum bloqueio colocado no banco de dados. Contudo haver ocasies em que voc ir querer bloquear um conjunto de registros antes de alter-los em seu programa PL/SQL. Isto pode ser feito usando a clusula FOR UPDATE da instruo SELECT: declare c_customers is select name,phone from customers for update; Laos

A capacidade de usar laos uma das principais diferenas entre SQL e PL/SQL, assim, isto algo que deve ser muito bem entendido. Existem trs construes de laos em PL/SQL que so muito simples e fceis de entender. O lao simples O lao simples tambm conhecido como lao infinito. A sintaxe para o lao simples : loop instrues executveis exit when condio true end loop; Vamos tentar um exemplo. Entre com o seguinte na sua sesso do sql*plus: set serveroutput on declare i number := 1; begin dbms_output.enable(100000); loop dbms_output.put_line(i); i := i + 1; exit when i > 10; end loop; end;

Quando executar o cdigo voc deve ver os nmeros de 1 a 10 impressos na tela. O cdigo continua at que a clusula exit equaciona true. Da o nome de lao infinito. As instrues de dbms_output so chamadas a um pacote do banco de dados que exibem sada em PL/SQL. Voc usa o lao simples quando voc no sabe quantas vezes voc quer que o lao execute e voc quer que o lao execute no mnimo uma vez. Laos numricos O lao numrico executar um certo nmero de vezes que foi definido no ndice do lao. A sintaxe para um lao numrico : for loop_index in lower_range .. upper_range loop instrues executveis end loop; set serveroutput on begin dbms_output.enable(10000); for i in 1 .. 10 loop dbms_output.put_line(i);

end loop; end;

O cdigo ser executado dez vezes. Isto est demonstrando uma forma diferente de obter o mesmo resultado. Voc usa o lao numrico quando voc quer executar o lao um nmero fixo de vezes e voc no quer que o lao termine prematuramente. Tambm possvel para o lao numrico fazer laos "para trs". Experimente o prximo exemplo: set serveroutput on begin dbms_output.enable(10000); for i in reverse 1 .. 10 loop dbms_output.put_line(i); end loop; end;

Este lao decrementar i de 10 at 1. O PL/SQL apenas incrementar ou decrementar o ndice de 1. A razo pela qual usamos laos em PL/SQL fazer mais do que exibir nmeros, os usamos principalmente para processar linhas de dados trazidas do banco de dados. Podemos usar ou o lao simples ou o lao for para processar dados. Aqui est um exemplo usando o lao simples: begin declare cursor c_students is select * from students; student_rec c_students%rowtype; begin open c_students; loop fetch c_students into student_rec; exit when c_students%notfound; end loop; close c_students; end; end; /

Aqui est outro exemplo usando o lao for com cursores: declare cursor c_students is select * from students; begin for c_students_rec in c_students

loop null; end loop; end; /

Se a segunda forma menor por que usar o lao simples? O lao simples melhor se precisarmos decidir o trmino do lao baseando-se em valores retornados em um fetch. O lao WHILE O lao WHILE um lao condicional que executar enquanto a condio do teste for avaliada como TRUE. Vamos tentar um exemplo. Entre o seguinte na sua sesso sql*plus: set serveroutput on declare i number := 0; begin dbms_output.enable(1000); while i < 10 loop i := i + 1; dbms_output.put_line(i); end loop; end; /

Quando usamos o lao WHILE no estamos certos de quantas vezes o lao deve ser executado e voc no tem que executar o lao no mnimo uma vez. O teste para a execuo do lao acontece antes do lao acontecer assim possvel que o lao no seja executado.