ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

sql server, cursores aninhados

 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
brunof
Novato
Novato


Registrado: Domingo, 4 de Agosto de 2013
Mensagens: 11

MensagemEnviada: Sáb Ago 10, 2013 10:15 pm    Assunto: sql server, cursores aninhados Responder com Citação

Fala aí galerinha, beleza ? Então, no meu BD em SQL Server, o cliente está relacionado com as receitas, o cliente também está relacionado com as vendas, que estão relacionados com os itens que estão relacionados com as parcelas... Eu sou iniciante em sql e tentei fazer o cursor, ele funciona parcialmente, ele exclui todas as receitas, e todas as parcelas, itens de uma única venda, ou seja, se um cliente tem 12 vendas, teria que executar 12 vezes... Se alguém puder me ajude, segue o código:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_ExcluiCliente](@idCliente int) AS
BEGIN

DECLARE @idVenda INT
DECLARE @idItemVenda INT
DECLARE @idItemVendaOutro INT
DECLARE @idParcela INT
SELECT @idVenda = idVenda FROM Vendas WHERE idCliente = @idCliente
SELECT @idItemVenda = idItemVenda FROM ItemVenda WHERE idVenda = @idVenda
SELECT @idItemVendaOutro = idItemVendaOutro FROM ItemVendaOutro WHERE idVenda = @idVenda
SELECT @idParcela = idParcela FROM ParcelasVenda WHERE idVenda = @idVenda

DECLARE cursorVenda CURSOR FOR (SELECT idVenda FROM Vendas WHERE idVenda = @idVenda)

--Abrir o cursor
OPEN cursorVenda --Quando vc abre o cursor ele está no BOF (begin of file)
--Mover o ponteiro(aponta para o registro em uso) do recordset
FETCH NEXT FROM cursorVenda INTO @idVenda
--Loop para percorrer os registros do recordset linha-a-linha
WHILE (@@FETCH_STATUS=0)
BEGIN
select @@fetch_status
if(@@FETCH_STATUS=0)
BEGIN

DECLARE cursorParcela CURSOR FOR(SELECT idParcela FROM ParcelasVenda WHERE idVenda = @idVenda)
OPEN cursorParcela
FETCH NEXT FROM cursorParcela INTO @idParcela
select @@fetch_status
WHILE (@@FETCH_STATUS=0)
BEGIN
DELETE FROM ParcelasVenda WHERE idParcela = @idParcela
FETCH NEXT FROM cursorParcela INTO @idParcela
END
CLOSE cursorParcela
DEALLOCATE cursorParcela


DECLARE cursorItemVenda CURSOR FOR(SELECT idItemVenda FROM ItemVenda WHERE idVenda = @idVenda)
OPEN cursorItemVenda
FETCH NEXT FROM cursorItemVenda INTO @idItemVenda
select @@fetch_status
WHILE (@@FETCH_STATUS=0)
BEGIN
DELETE FROM ItemVenda WHERE idItemVenda=@idItemVenda
FETCH NEXT FROM cursorItemVenda INTO @idItemVenda
END
CLOSE cursorItemVenda
DEALLOCATE cursorItemVenda


DECLARE cursorItemVendaOutro CURSOR FOR(SELECT idItemVendaOutro FROM ItemVendaOutro WHERE idVenda=@idVenda)
OPEN cursorItemVendaOutro
FETCH NEXT FROM cursorItemVendaOutro INTO @idItemVendaOutro
select @@fetch_status
WHILE (@@FETCH_STATUS=0)
BEGIN
DELETE FROM ItemVendaOutro WHERE idItemVendaOutro=@idItemVendaOutro
FETCH NEXT FROM cursorItemVendaOutro INTO @idItemVendaOutro
END
CLOSE cursorItemVendaOutro
DEALLOCATE cursorItemVendaOutro

--Declaração do cursor
DECLARE cursorCliente CURSOR FOR (SELECT idCliente FROM receitas WHERE idCliente = @idCliente)
--Abrir o cursor
OPEN cursorCliente --Quando vc abre o cursor ele está no BOF (begin of file)
--Mover o ponteiro(aponta para o registro em uso) do recordset
FETCH NEXT FROM cursorCliente INTO @idCliente
--Loop para percorrer os registros do recordset linha-a-linha
select @@fetch_status
WHILE (@@FETCH_STATUS=0)
BEGIN
DELETE FROM receitas WHERE idCliente=@idCliente
FETCH NEXT FROM cursorCliente INTO @idCliente
END
--Fechar o cursor
CLOSE cursorCliente
--Desalojar o cursor da memória
DEALLOCATE cursorCliente



END
DELETE FROM Vendas WHERE idVenda=@idVenda
FETCH NEXT FROM cursorVenda INTO @idVenda
END
--Fechar o cursor
CLOSE cursorVenda
--Desalojar o cursor da memória
DEALLOCATE cursorVenda


--DELETE FROM Clientes WHERE idCliente = @idCliente
END
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
brunof
Novato
Novato


Registrado: Domingo, 4 de Agosto de 2013
Mensagens: 11

MensagemEnviada: Dom Ago 11, 2013 1:54 am    Assunto: Aparentemente resolvido Responder com Citação

Além de ser iniciante, depois de muito tempo sem dormir, cometi um erro básico na declaração do primeiro cursor

DECLARE cursorVenda CURSOR FOR (SELECT idVenda FROM Vendas WHERE idVenda = @idVenda)

ali no idVenda = @idVenda, tinha que ser idCliente = @idCliente, mas aproveitando que já abri o tópico, se alguém tiver alguma dica de cursor, ou da otimização desse código, fique á vontade!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Seg Ago 12, 2013 11:15 am    Assunto: Responder com Citação

Bom dia,

Acho que você talvez possa utilizar a opção On Delete Cascade para excluir os registros das tabelas conforme exemplo do artigo abaixo:
http://www.codeproject.com/Articles/620086/CASCADE-in-SQL-Server-with-example

Também acho que é possível utilizar a sintaxe do Delete com Join para excluir os registros sem utilizar cursor.
Ou se for para utilizar cursor, acho que o mesmo poderia ser utilizado apenas para a tabela Vendas, sendo que para as outras tabela seria utilizado um Delete simples.

Espero que ajude.


Editado pela última vez por imex em Ter Out 03, 2023 4:15 pm, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
brunof
Novato
Novato


Registrado: Domingo, 4 de Agosto de 2013
Mensagens: 11

MensagemEnviada: Ter Ago 13, 2013 12:41 am    Assunto: Obrigado! Responder com Citação

Novamente te agradeço Imex, utilizando o "On DELETE CASCADE" eu consegui retirar 80% dos cursores que utilizava. Muito Obrigado!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados Todos os horários são GMT - 3 Horas
Página 1 de 1

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB