Cursores são utilizados quando precisamos tratar cada linha da consulta de forma indvidual. Para isso utilizamos Cursores, que não é nada mais que um select onde o resultado é retornado linha a linha.
Parece simples não é mesmo?
Bem, aqui vai um roteiro simples de como trabalhar com cursores:
1º declarar cursor
declare Cur_pessoas Cursor
for select Nome, idade from Pessoas
Note que precisamos tbm definir as variaveis de saida
Logo, noso script vai ficar assim:
declare @Nome varchar
declare @Idade numeric
declare Cur_pessoas Cursor
for select Nome, idade from Pessoas
2º Abrir o cursor
Open Cur_Pessoas
Neste momento a consulta já foi feita e está armazenada em cash, agora precisamos recuperar a primeira linha do cursor:
3º Recuperando registros do cursor:
Lembra das duas variáveis que foram criadas? Agora está na hora de utiliza-las, foi criada 1 variável para recuperar cada coluna da consulta, pessoalmente eu acho mais conveniente que criar uma variável do tipo tabela, mas isso fica ao seu critério.
fetch next from Cur_Pessoas into @Nome, @Idade /*A ordem é importante*/
Ok, agora que temos o primeiro registro precisamos fazer um laço e tratar cada registro de forma induvidual.
while (@@fetch_status = 0 ) /*@@Fetch_Status é uma variável do SQL server que indica se um cursor retornou algum registro após o fetch*/
begin
/*Aqui vc faz os tratamentos necessários*/
if exists ( select Nome from Clientes
where nome like '@Nome'
and Idade > @Idade) begin
Update Clientes
Set AlgumField = AlgumaCoisa
where nome like '@Nome'
and Idade > @Idade
/*Não podemos esquecer de pegar o proximo registro*/
fetch next from Cur_Pessoas into @Nome, @Idade
end
end /*While*/
/*Finalizar e desalocar cursor*/
close Cur_Pessoas
deallocate Cur_Pessoas
----------------------------------------------------------------------------------------
Os cursores são muito úteis, mas seu uso deve ser evitado, já que eles consomem mtos recursos da sua máquina. Em outras palavras, use apenas se for estritamente necessário.
Segue um exemplo mais completo ( Retirado de: http://www.linhadecodigo.com.br/Artigo.aspx?id=876 )
create procedure BaixaEstoque( @VenCod Integer) as
--Declarando cursor
DECLARE CurItens --Nome do cursor
CURSOR FOR
SELECT ProdCod, IVQtd FROM Itens WHERE VenCod = @VenCod
--Variáveis utilizadas para o tratamento dos registors
DECLARE @ProdCod INTEGER, @IVQtd MONEY
--Iniciando transação
BEGIN TRANSACTION
--Abrindo cursor
OPEN CurItens
--Atribuindo valores do select nas variáveis
FETCH NEXT FROM CurItens INTO @ProdCod, @IVQtd
--Iniciando laço
WHILE @@FETCH_STATUS = 0
BEGIN
IF (SELECT ProdQtdEst - @IVQtd FROM Produtos WHERE ProdCod = @ProdCod) >= 0
UPDATE Produtos
SET ProdQtdEst = ProdQtdEst - @IVQtd
WHERE ProdCod = @ProdCod
ELSE
BEGIN
--Desfazendo o que foi realizado anteriormente
ROLLBACK TRANSACTION
--Levantando erro
RAISERROR(‘Estoque insuficiente!’, 15, 1)
--Fechando e desalocando cursor aqui também, pois o return sairá do procedimento
CLOSE CurItens
DEALLOCATE CurItens
--Saindo do procedimento
RETURN
END
--Próxima linha do cursor
FETCH NEXT FROM CurItens INTO @ProdCod, @IVQtd
END
--Fechando e desalocando cursor
CLOSE CurItens
DEALLOCATE CurItens
--Caso tudo tenha ocorrido OK, alterando a situação da venda
UPDATE Vendas
SET VenSit = 1
WHERE VenCod = @VenCod
--Confirmando transação
COMMIT TRANSACTION
quarta-feira, 16 de janeiro de 2008
Assinar:
Comentários (Atom)