quarta-feira, 3 de dezembro de 2008

Operação de várias etapas gerou erro. Verifique cada valor de status.

Erro genérico da middleware OLE DB

Mensagem de exceção genérica, presumo (hehehhe...), da Ole Db. A mesma mensagem pode ser recebida ao inserir, alterar, excluir, ou até mesmo consultar, dados. Diversas vezes, em empresas diferentes ao dar manutenção em softwares (alguns muito imbicados, outros nem tanto) passei por essa situação. Há algum tempo imaginei postar a respeito. A princípio, não há nada neste problema que mereça destaque. Todavia, um pequeníssimo detalhe me chamou a atenção para tal.
A pior situação que vivenciei ao receber este erro foi com a seguinte configuração: Oracle e Delphi, usando ADO. O problema acontecia quando um determinado registro era carregado para tela e em decorrência era disparada a seguinte exceção: “Operação de várias etapas gerou erro.Verifique cada valor de status”. Obviamente, esse detalhe, de que era apenas um registro específico que causava o problema, só foi percebido depois de algum tempo perdido em função de estarmos concentrados em resolver um incident report, o qual descrevia que a determinada tela do sistema não estava funcionando. A tela do sistema não esta funcionando! Anexo ao incidente havia um screenshot com a mensagem de exceção e mais nada.
Apesar de estarmos certos de que o problema era o registro, foi bastante cansativo e demorado encontrar em que dado específico estava a causa do problema. A tela em questão envolvia pelo menos três tabelas tabelas. Sendo que duas delas (as principais, master/detail) possuíam, cada uma, mais de duzentas colunas. Contudo, num dos casos isso foi totalmente relevante porque por mais que observássemos os dados o problema era invisível. Como??? Pois é, isso mesmo, não dava pra perceber simplesmente usando um “select * from ... where ...”


Processo de identificação do dado defeituoso:


Primeiro, num ClientDataset de cada vez, excluímos todos os TFields. Em seguida fomos adicionando um TField de cada vez, então ativávamos o ClientDataset. e testávamos. Assim , encontramos o dado que apresentava problema. Não era possível ver o valor nem debugar. A exceção era disparada imediatamente ao método “Open” ser chamado. É claro, suponho que alguém possa sugerir, debuggar nas units do Delphi (a própria ADODb). Todavia, no nosso caso isso seria pouco eficiente porque nesta situação específica, os desenvolvedores originais do sistema haviam alterado a ADODb. Além de outras units importantes (é desnecessário dizer que eles haviam prejudicado bastante a biblioteca. Na minha opinião, destruíram as units). Além disso, haviam várias chamadas a centenas de funções bizonhas, desnecessárias e confusas (uma rara coletânea de bozosorts anhinhados). Era uma verdadeira "visão Dantesca" (Deus me livre e guarde!). Seria muito simplório também imaginar ser possível substituí-las pelas originais (Existem loucos que conseguem inventar problemas mais complicados que as soluções seriam, se fossem razoavelmente implementadas). Pode acreditar, eu tenho vergonha de mencionar essas coisas e trazer a luz fatos como esses...
Em fim, não era possível na aplicação Delphi identificar o valor do campo, tratava-se de um campo “Date”, ou “DateTime”. Tranqüilo, basta um select do PL/SQL Developer!! Que nada. "Select" feito, a data estava lá, perfeita. Sei lá, tipo “12/11/05”. Ué tudo certo com esse valor?!??!?! Parece que sim ... então ...
O Que fazer? Cara, faz um cast para string ... resultado: “12/11/00”. Só que, cansado, na tensão do problema, é bem provável que vc não consiga distinguir entre “12/11/00” e “12/11/05”. Mas, se usar a mascará “DD/MM/YYYY” fica mais fácil ver a diferença entre “12/11/0005” e “12/11/2005”.


Pois é amigo, isso acontece! Vi muita gente boa perder tempo e stress nessa sinuca de bico.
Hoje, ao socorrer um amigo, tive tempo para documentar e fiz alguns screenshots para demonstrar o problema.



Forçando a exceção em tempo de projeto: Atribuindo valor para o parâmetro, em seguida ativando o ClientDataset.




Exceção, mensagem, recebida no Delphi ...




No Oracle, o que víamos não apresenta falha. A data, aparentemente, era exibida como se estivesse correta ...




Não confiando no que os olhos viam superficialmente, procuramos um pouco mais....



Alteramos a data e tudo ficou bem. Problema resolvido! Só que, hoje, sem sofrimento.

update CadZnCotryDm set dat_nasc= to_date('25/03/2004', 'dd/mm/yyyy')
where cic='0618XXXXXX019X';

Isso também aconteceu, anteriormente com campos strings cujo valor possuía caracteres acentuados que de alguma forma ao serem persistidos eram substituídos por caracteres estranhos, tipo. “Maria das Gra¿as”.
Esse problema encontra-se dentro do escopo de problemas que descrevi no artigo “Banco de Dados ou Bando de Dados”. Esse é mais um exemplo de como poderá ser custoso no futuro para uma empresa manter um banco de dados o qual aceita que qualquer valor possa ser inserido nele. A qualquer momento caba entrando lixo, visto que não existem regras que determinem o que pode ou não ser persistido em suas tabelas.

6 comentários:

  1. Valeu !!!!!!!!!!!!!!!!!!!!!!!!!!!!

    ResponderExcluir
  2. VALEUUU!!! DEUS TE ABENÇOEEE!!!!
    E abençoe o google tbem por ter achado esse post! heheh
    Estava trabalhando na conversão de um BD exatamente no mesmo senário que o seu, Delphi + oracle + Data defeituosa...
    Aparecia esse erro, mas "Visualmente" a data estava perfeita... mas gerando erro!

    Valeu mesmo parceiroo!!!!! Salvou meu dia heheh

    ResponderExcluir
  3. Valeu mesmo, Post nota 1000... Resolveu meu problema.

    ResponderExcluir
  4. Muito obrigado pela sua dica salvadora!

    ResponderExcluir
  5. Cara muitissimo obrigado, era ezatamente a data !!
    Putz, se salvou meu dia.

    ResponderExcluir

 
BlogBlogs.Com.Br