Valor é somado duas vezes ao invés de uma

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
joaoluizbt
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 37
Registrado em: Qui, 05 Mai 2011 3:53 pm
Localização: Rio de Janeiro

Olá,

Eu tenho uma tabela e um dos campos precisa ser atualizado somando-se seu valor com o de outra tabela.
eu usei o decode, mas ele está somando o valor do campo da segunda tabela duas vezes. tem algum problema no codigo do decode?

Selecionar tudo

update tebela1 ect
set VALOR_PAGO = nvl(valor_pago,0) + decode((select pa.valor                         
                                      from tabela2 pa 
                                      where pa.codigo = ect.codigo), 
                                      null, 0,
                                      (select pa.valor                         
                                      from tabels2 pa 
                                      where pa.codigo = ect.codigo));
Muito obrigado.
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

Joaoluizbt,

Não estou acostumado a fazer um UPDATE desta forma, mas já que você usou NVL, por que não em toda a sua querie, substituindo o DECODE?

Não testei aquí, mas veja se esta querie ajudaria você:

Selecionar tudo

UPDATE tabela1 ect 
   SET valor_pago = NVL(valor_pago,0) +
                    NVL((SELECT pa.valor FROM tabela2 pa WHERE pa.codigo = ect.codigo),0)
Pode ser que os colegas do forum tenham outras soluções mais interessantes.

Abraços,

Sergio
joaoluizbt
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 37
Registrado em: Qui, 05 Mai 2011 3:53 pm
Localização: Rio de Janeiro

oi,

na verdade eu tenho um problema fazendo deste jeito.

se a tabela 1 tiver um código que não existe na tabela 2, o select não vai retornar nada, aí a soma vai dar nulo e o valor da tabela 1 que deveria permanecer será trocado por nulo, prejudicando o calculo.

com o decode eu garanto que, caso o select não retorne nada, eu somo com o valor zero.

o problema é esta duplicidade.
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

joaoluizbt,

No exemplo que te passei, se o SELECT não retornar registros, o valor retornaria NULL e então seria imediatamente tratado pelo NVL :

Selecionar tudo

 ... NVL((SELECT ... FROM .. WHERE ...),0)
Você chegou a fazer um teste com NVL+SELECT ?

Concordo com você de que o DECODE não deveria estar retornando mais de um valor. Não me recordo de ter visto algo parecido com isso antes.

Muito estranho os problemas relatados por você:

- DECODE que duplica valores;
- UPDATES que - uma vrz ou outra - "erram" no calculo;

Pontos para você avaliar?
- Será que está ocorrendo algum problema com o seu ambiente?
- Você instalou algum parche no banco?
- O release do seu banco está obsoleto?
- Será que tem alguma trigger - que você desconheça - que esteja sendo disparada nos updates?
- Os erros que você está relatando (DECODE/UPDATE) se referem exatamente à mesma tabela?
- Os índices desta tabela estão OK? Tentou fazer ALTER INDEX REBUILD nos índices?
- Tentou reconstruir a tabela com ALTER TABLE MOVE ?

Estas duas últimas sugestões talvez nada tenham a ver com os problema, mas eu não descartaria você executar no ambiente, só para ver se resolve algo.

Talvez outro usuário do forum possa dar uma opinião sobre o assunto, mas sinto que tem algo errado com o seu ambiente.

Na falta de outra sugestão de forista, eu diria para você também fazer um teste com NVL+SELECT.

Abraços,

Sergio Coutinho
marcus.kobel
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 45
Registrado em: Qui, 12 Mai 2011 4:54 pm
Localização: Porto Alegre - RS

É, não deveria te dar problema o DECODE(), mas uma sugestão que fica é de debugar os teus SELECTs que tão dentro do DECODE().
Pega um caso específico onde tu diz que o resultado final fica "duplicado" e vê o que está acontecendo. Roda cada um dos SELECTs com o ID da tabela1 e vê quais valores eles retornam. Eu jogo contigo que são erros nos dados ou erro seu. É difícil ser erro no banco...

Valeu!
joaoluizbt
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 37
Registrado em: Qui, 05 Mai 2011 3:53 pm
Localização: Rio de Janeiro

Oi pessoal.

Diante desses fenômenos sobrenaturais, eu tomei uma ação radical e rudimentar...
criei uma tabela para o valorpago, uma tabela para o outro valor e uma terceira para a soma, depois pego tudo da terceira e atualizo a tabela 1.

tendo que entregar "para ontem" agente acaba não utilizando as melhores práticas...

de qualquer forma valeu a todos pela ajuda.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante