Usuário com melhor resposta
Dúvida Procedure

Pergunta
-
Bom Tarde, foi criado uma procedure no sistema, para dar o update para os clientes que possuem conta inativas, conforme verificado abaixo:
CREATE procedure [dbo].[status_financeiro] as declare @id_pessoa int , @valor int declare CursorParcela cursor for select pessoa_id from dbo.contas_receber where data_tolerancia < CONVERT (date, GETDATE()) and quitado = 0 open CursorParcela fetch next from CursorParcela into @id_pessoa while @@fetch_status = 0 begin update dbo.pessoa set dbo.pessoa.status_financeiro = 'Bloqueado' where id = @id_pessoa fetch next from CursorParcela into @id_pessoa end close CursorParcela deallocate CursorParcela
Porém vi que estava demorando demais, para executar, as vezes até dava erro de timeout, fui fazer o select, porém me retorna muitos registros, quase 70000, ou seja serão feitos 70000 updates, não sei como posso fazer para economizar tempo nessa procedure, para que não demore tanto, e nem dê erro, obrigado.
Respostas
-
Já tentou fazer sem o uso do cursor?
Voce pode fazer um update usando join na tabela dbo.contas receber
- Marcado como Resposta Mariana C. Costa quarta-feira, 22 de fevereiro de 2017 17:20
-
Boa tarde,
Mariana, segue uma sugestão sem Cursor para teste:
update p set status_financeiro = 'Bloqueado' from dbo.pessoa as p where exists (select 1 from dbo.contas_receber as r where r.pessoa_id = p.id and r.data_tolerancia < CONVERT (date, GETDATE()) and r.quitado = 0)
Espero que ajude
Assinatura: http://www.imoveisemexposicao.com.br
- Marcado como Resposta Mariana C. Costa quarta-feira, 22 de fevereiro de 2017 17:20
Todas as Respostas
-
Já tentou fazer sem o uso do cursor?
Voce pode fazer um update usando join na tabela dbo.contas receber
- Marcado como Resposta Mariana C. Costa quarta-feira, 22 de fevereiro de 2017 17:20
-
Boa tarde,
Mariana, segue uma sugestão sem Cursor para teste:
update p set status_financeiro = 'Bloqueado' from dbo.pessoa as p where exists (select 1 from dbo.contas_receber as r where r.pessoa_id = p.id and r.data_tolerancia < CONVERT (date, GETDATE()) and r.quitado = 0)
Espero que ajude
Assinatura: http://www.imoveisemexposicao.com.br
- Marcado como Resposta Mariana C. Costa quarta-feira, 22 de fevereiro de 2017 17:20
-
-
-
Boa Tarde, eu simplesmente coloquei o distinct para poder dar update somente uma vez, pois se a pessoa tivesse com 22 contas em atraso, o update seria realizado, 22 vezes, testei sem o cursor, com a mesma lógica, e o tempo, foi praticamente o mesmo, muito obrigado.
-
Mariana,
Quais índices estão presentes na table Pessoas?
Pedro Antonio Galvao Junior [MVP | MCC | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
-
Bom dia Junior,
A tabela pessoas, possui um status financeiro, informando se está bloqueado ou liberado, esse status é atualizado nessa procedure, ele verifica se possui contas vencidas, da data de hoje, para trás, e se houver o update é Bloqueado, porém como tem muitas contas, se houvesse 30 contas em atraso da mesma pessoa, seria realizado 30 updates no mesmo cadastro, dai utilizei o distinct. Não sei se foi a forma correta, porém diminuiu bem o tempo de execução da procedure.
-
Mariana,
Dizer se é a melhor forma de longe não é fácil, mas seria interessante tentar entender e analisar o plano de execução.
Provavelmente ao usar o distinct você forçou o SQL Server é mudar o plano de execução principalmente no que diz respeito a dados que podem ser similares.
Pedro Antonio Galvao Junior [MVP | MCC | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
-