none
Dúvida Procedure RRS feed

  • 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. 

    quarta-feira, 22 de fevereiro de 2017 15:17

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
    quarta-feira, 22 de fevereiro de 2017 15:21
  • 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
    quarta-feira, 22 de fevereiro de 2017 15:28

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
    quarta-feira, 22 de fevereiro de 2017 15:21
  • 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
    quarta-feira, 22 de fevereiro de 2017 15:28
  • mesmo fazendo inner join, a quantidade de registros seria a mesma, estou tentando fazer testes, ainda não tentei sem fazer o cursor, estou verificando. 
    quarta-feira, 22 de fevereiro de 2017 15:30
  • Na teoria sem o cursor dever ter desempenho melhor
    quarta-feira, 22 de fevereiro de 2017 15:42
  • 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.
    quarta-feira, 22 de fevereiro de 2017 17:20
  • 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]

    quarta-feira, 22 de fevereiro de 2017 18:42
  • 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. 

    quinta-feira, 23 de fevereiro de 2017 11:48
  • 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]

    terça-feira, 28 de fevereiro de 2017 19:43
  • Como eu precisava de uma solução rápida Junior, essa foi a q mais me atendeu, em pouco tempo, pois eu só precisava do update em cada cliente, uma vez, estarei analisando e se houver melhor resultado, postarei o resultado. Obrigado.
    quinta-feira, 2 de março de 2017 12:16