Você está na página 1de 23

Hugo Pedro Proena, 2007

Cursores - Necessidade

O dono de uma livraria cuja base de dados administrada por si pediu-lhe para efectuar as seguintes alteraes ao preo dos livros:
Os livros que custarem mais de 10 , devem ver o seu preo diminudo em 10%. Os restantes devem sofrer um aumento de 15% 15%

Este tipo de problemas no pode ser resolvido Q , ou da execuo atravs de um nico bloco SQL, sequencial de 2 blocos.
No previne a dupla alterao em livros com valor muito prximo de 10.

Hugo Pedro Proena, 2007

Cursores

Constituem uma forma de aceder individualmente a cada linha de um conjunto de dados. dados
Realizao de mltiplas operaes sobre cada instncia Distino i i entre as aces a executar sobre b instancias

Fornecem um apontador p p para cada instancia do conjunto de dados


Manipulao sequencial deste apontador

Hugo Pedro Proena, 2007

Cursores

Tipos de Cursores
Server Side
Constituem objecto de estudo desta disciplina e so manipulados pelo SGBD.

Client Side
So pedidos lotes de informao ao servidor que posteriormente so guardadas num buffer. Do lado do cliente cliente, existem bibliotecas de funes que simulam a utilizao de cursores.

Hugo Pedro Proena, 2007

Cursores

Etapas de Utilizao
Na utilizao de cursores com o SQl Server (como na g ( generalidade dos SGBD), ), identificamse 5 fases: Declarao Nesta fase validade a instruo de consulta que suporta o cursor e criadas as estruturas de dados para a sua implementao. OPEN Abertura do cursor cursor. Permite ao SGBD guardar as chaves primrias das instancias envolvidas por forma a facilitar o acesso

Hugo Pedro Proena, 2007

Cursores

Etapas de Utilizao
FETCH Nesta fase o cursor devolve a informao relativa instancia para onde aponta e incrementa a sua posio. CLOSE Fecha o cursor. Esta operao permite libertar quaisquer bloqueios utilizados para garantir a consistncia da informao. informao DEALLOCATE Liberta a memria alocada para a utilizao do cursor.

Hugo Pedro Proena, 2007

Cursores

Declarao de Cursores DECLARE <nome_cursor> [SCROLL] [INSENSITIVE] CURSOR FOR <bloco_selecao> [FOR {READ ONLY | UPDATE } ] INSENSITIVE Aces executadas por outros
utilizadores durante a manipulao do cursor no so tidas em conta

SCROLL Oposto da opo anterior. Permite ao cursor


ler de operaes executadas por outros utilizadores durante a manipulao do cursor. Permite tambm a fl ibili flexibilizao d das operaes d de acesso informao. i f

Hugo Pedro Proena, 2007

Cursores

Declarao de Cursores implica inibe as READ ONLY Como o nome implica, alteraes informao. Internamente permite muito maior eficincia no acesso informao (nmero e tipo de bloqueios necessrios). Sempre que um cursor no altere a informao, deve ser declarado com esta opo. UPDATE Opo oposta anterior. Permite a actualizao de um conjunto de colunas da tabela.

Hugo Pedro Proena, 2007

Cursores

Declarao de Cursores Exemplo


DECLARE Cursor_Exemplo SCROLL CURSOR FOR SELECT CodEmpregado, p g , Nome FROM Empregado ORDER BY Nome GO

Hugo Pedro Proena, 2007

Cursores

Abertura de Cursores
Aps a declarao do cursor necessrio executar a sua abertura antes de poder aceder informao. Para isso, basta utilizar a seguinte sintaxe: OPEN <nome_cursor> <nome cursor> Para o exemplo atrs descrito: OPEN Cursor_Exemplo

Hugo Pedro Proena, 2007

Cursores

Acesso informao
Tendo o cursor declarado e aberto, pode-se aceder individualmente a cada uma das instncias do conjunto de dados. Sintaxe:
FETCH [NEXT | PRIOR | FIRST | LAST | ABSOLUTE <n> | RELATIVE <n>] FROM <nome_cursor> <nome cursor> [INTO @variavel1, ..., @variavelN]

Hugo Pedro Proena, 2007

Cursores

Acesso informao
NEXT Corresponde operao por omisso. da p prxima instncia Permite a devoluo disponvel. PRIOR Oposto clausula anterior. Permite o acesso ultima instncia que terminou de ser acedida. did FIRST Permite o acesso primeira instancia do conjunto de dados LAST Permite o acesso ultima instancia do conjunto de dados. ABSOLUTE <N> Permite aceder N-esima instancia do conjunto de dados

Hugo Pedro Proena, 2007

Cursores

Acesso informao
RELATIVE <N> Permite aceder N-sima instancia do conjunto de dados a contar da ultima instancia a ser acedida, isto , posio relativa do cursor. FROM Especifica o cursor a que se pretende aceder. INTO Normalmente a informao recebida do cursor guardada em variveis variveis. Esta clusula permite identificar as variveis destino da informao.

Hugo Pedro Proena, 2007

Cursores

Acesso informao Exemplo


NO caso do exemplo utilizado, poderiamos aceder individualmente a cada linha da tabela da seguinte forma:
FETCH NEXT FROM Cursor_Exemplo INTO @var WHILE @@fetch_status = 0 BEGIN ... FETCH NEXT FROM C Cursor_Exemplo E l INTO @var END

Hugo Pedro Proena, 2007

Cursores

Fecho do Cursor
Aps terem sido executadas todas as operaes pretendidas pela utilizao do cursor pode-se proceder ao seu fecho. Este simplesmente feito atravs da sintaxe:
CLOSE <nome_cursor>

NO exemplo descrito nos slides anteriores, b bastaria i executar:


CLOSE cursor_exemplo

Hugo Pedro Proena, 2007

Cursores

Libertao de recursos
Mesmo aps o fecho do cursor, o SGBD mantm um conjunto de estruturas de dados alocadas para prevenir a eventual reabertura do cursor. Quando garantido que no sero executadas mais operaes sobre o cursor, , deve-se p proceder libertao explcita dos recursos utilizados. Para isso basta utilizar a sintaxe:
DEALLOCATE <nome_cursor> <nome cursor>

Para o exemplo descrito, bastaria:


DEALLOCATE cursor_exemplo

Hugo Pedro Proena, 2007

Cursores / Variveis
A utilizao de cursores pressupe normalmente a declarao de variveis que vo guardar a informao proveniente dos cursores. Para declarar uma varivel num bloco T-SQL basta utilizar a sintaxe: DECLARE @<nome_variavel1> <tipo1>, ... @<nome_variavelN> <tipoN>

Exemplo: DECLARE @codigo int, @nome VARCHAR(100) @tempo datetime

Hugo Pedro Proena, 2007

Cursores / Variveis
Caso o bloco de seleco do cursor devolva mais que uma coluna, sera necessrio declarar tantas variveis quanto o nmero de colunas. Exemplo: DECLARE c1 CURSOR FOR SELECT Codigo, Nome, Idade FROM Empregado Q Quando fosse necessrio aceder informao teria q que ser executado o seguinte bloco: FETCH c1 INTO @var1, @var2, @var3

Hugo Pedro Proena, 2007

Cursores / Variveis
Uma soluo mais prtica consiste na declarao de variveis/estrutura que contm internamente tantos campos quantas as colunas devolvidas pelo cursor. Exemplo: DECLARE CURSOR C1 FOR SELECT Codigo, Nome FROM Empregado, @var C1@ROW_TYPE Neste caso @var vai conter 2 campos Codigo e Nome. Para aceder a cada um deles basta colocar @var.Codigo ou @var.Nome

Hugo Pedro Proena, 2007

Cursores / Variveis

Este tipo de variveis simplifica bastante a recolha de informao proveniente do cursor, que desta forma pode passar a ser feita simplesmente na forma:

FETCH NEXT C1 INTO @var

Como @var est declarada como sendo do mesmo tipo que as instancias de C1, ser totalmente preenchida por todos os atributos da instncia que estiver a ser acedida. acedida

Hugo Pedro Proena, 2007

Cursores

O problema de actualizao dos preos dos livros poderia facilmente ser resolvido atravs da utilizao de cursores: DECLARE C1 CURSOR FOR SELECT price FROM titles FOR UPDATE, @preco p float /* Declarao do cursor. Explicitado que servir para actualizar informao*/ GO

Hugo Pedro Proena, 2007

Cursores
OPEN C1 FETCH NEXT FROM C1 INTO @preco /*recepo / recepo da primeira instancia instancia*/ / WHILE @@fetch_status=0 BEGIN /* Para todas as instancias / instancias*/ / if @preco<10 UPDATE Titles SET price=price*1.15 price=price*1 15 WHERE CURRENT OF C1 /*Bloco que permite actualizar o valor da instncia actualmente apontada pelo cursor cursor*/ /

Hugo Pedro Proena, 2007

Cursores
else UPDATE Titles SET Price=Price Price=Price*0 0.9 9 WHERE CURRENT OF C1 FETCH NEXT FROM C1 INTO @preco END /* / Fim do While */ / CLOSE C1 DEALLOCATE C1 /* fecho e libertao de recursos*/

Hugo Pedro Proena, 2007

Cursores - Exerccio

Crie um cursor para a tabela Authors da base de dados pubs do SQL Server. Leia d desse cursor o primeiro i i e ultimo lti nome do d autor, bem como o estado de onde originrio. g Para os autores originrios g da California, imprima os nomes (primeiro e ultimo) do autor juntamente com o texto (mora (mora na California) California) . Caso contrrio, basta imprimir o primeiro e ultimo nome do autor