Erro ao comparar ou armazena campos numericos com Dbexpress

Delphi

21/02/2012

Galera,

alguém sabe me dizer comno resolve isso ?

Preciso apenas comparas se o valor de um campo do tipo DECIMAL
é <= 0

Porem quando faço isso

if cdEstoque.fieldbyname(quantidade).asfloat <=0 then

me apresenta o seguinte erro:

raised exception class EconvertError with message = is not a valid floating point value

Ao debugar na linha da comparação, apontando o point do debug em cima do ASFLOAT:

if cdEstoque.fieldbyname(quantidade).asfloat <=0 then

o Debug apresenta o seguinte:

cdEstoque.fieldbyname(quantidade).asfloat = delphi execption EconvertError at $9A9F949

ou seja, é como se não tivesse valor ou fosse um valor inválido, porém, neste CAMPO tem valor Zero ou maior que zero, neste caso específico do teste é 1...

Uso D7 + dbexpress + FB 2.1 campos de tipo flutuante como DECIMAL(12,2)

Me ajuda aí ???

Jeremias

Jeremias

Curtidas 0

Respostas

Marco Salles

Marco Salles

21/02/2012

Amigo este campo quantidade é um camp agrregado ??? ou é fisico na tabela ??
GOSTEI 0
Marco Salles

Marco Salles

21/02/2012

Amigo este campo quantidade é um camp agrregado ??? ou é fisico na tabela ??


E depedendo da sua resposta caso seje físico , tente apagar este field no cds e no sql respectivamente

se for o caso (feche a conexão) apague , abra a conexão (SqlCoonection) e adicione o campo novamente

No caso de voce trabalhar com os fielde definidos , apesar de voce estar utilizando o fieldBynAme

o que implica em não necessariamente na adição desses campos
GOSTEI 0
Jeremias

Jeremias

21/02/2012

Amigo este campo quantidade é um camp agrregado ??? ou é fisico na tabela ??


É físico
GOSTEI 0
Jeremias

Jeremias

21/02/2012

Amigo este campo quantidade é um camp agrregado ??? ou é fisico na tabela ??


E depedendo da sua resposta caso seje físico , tente apagar este field no cds e no sql respectivamente

se for o caso (feche a conexão) apague , abra a conexão (SqlCoonection) e adicione o campo novamente

No caso de voce trabalhar com os fielde definidos , apesar de voce estar utilizando o fieldBynAme

o que implica em não necessariamente na adição desses campos


Ok, fiz como orientado Marcos, mas continua o mesmo erro...

A única diferença é que no meu caso eu uso apenas
1 sqlDataSet + 1 DataSetProvider genéricos pra pesquisas
aí linko os ClientDataSet ao DataSetProvider genérico com
sua propriedade AllowCommandText = True, dessa forma
altero apenas a propriedade CommandText dos ClientDataSet
conforme a necessidade da pesquisa, portanto os campos
ficam relacionados apenas no ClientDataSet com seus
flags configurados devidamente...

Fechei minha conexão, apaguei-os, abri a conexão novmanete
e adicionei-os e configurei os provider flags...

Fiz o teste e continua o maledito erro...

É bem esquisito isso ....

Não faz sentido ???????


A pesquisa funciona normal, tem lá o valor do campo quantidade = 1
mas na comparação ou na tentativa de armazenar o valor do campo quantidade
em uma variável de qualquer tipo dá esse erro aí...

Se usar AsFloat, AsCurrency ou AsVariante ou AsBcd tudo dá erro...

O que mais pode ser ????
GOSTEI 0
Marco Salles

Marco Salles

21/02/2012

pode ser o driver

voce disse que usa

Uso D7 + dbexpress + FB 2.1 campos de tipo flutuante como DECIMAL(12,2)

voce esta utilizando qual driver ???
GOSTEI 0
Jeremias

Jeremias

21/02/2012

pode ser o driver

voce disse que usa

Uso D7 + dbexpress + FB 2.1 campos de tipo flutuante como DECIMAL(12,2)

voce esta utilizando qual driver ???


É, pode ser ???????

Eu uso o Firebird com retrocompatibilidade com a GDS32.DLL portanto estou usando as configurações padrões que eu usava com o Interbase... Inclusive me banco continua com extensão GDB

É necessário usar um driver padrão do Firebrid neste caso ?

Se for, me dá umas dicas aí Marco Antonio...

Qual driver posso usar com esta versão, onde encontro e como configuro isso ai chapa ...

Se puder passar alguns exemplos era bom, hehehe

Me ajuda aí chapa ????
GOSTEI 0
Marco Salles

Marco Salles

21/02/2012

Calma Jeremias . To tentando

Problemas de Diver geralmente se deve a complexidade de Tipos ou de intruções Sql
a principio muito utilizam o próprio Driver do Interbase

1)
Esta Sql sua é complexa ou simples

2)
Tente utilizar o fieldByname no lugar do Tfield definido
apague todos para esta fazer este teste e utilize

cds.FieldByname(SeuCampo).TipoDeDaos

será que este teucampo Esta sendo carregado pelo Sql ???

faça este teste e nos retorne

ps) Por vafor quem quiser dar sugestões fiquem á vontade
este tópico é público
GOSTEI 0
Jeremias

Jeremias

21/02/2012

Calma Jeremias . To tentando

Problemas de Diver geralmente se deve a complexidade de Tipos ou de intruções Sql
a principio muito utilizam o próprio Driver do Interbase

1)
Esta Sql sua é complexa ou simples

Nada é simples... são 5 campoos veja:

cdsEstoque.Close;

cdsEstoque.CommandText := SELECT ID,ID_PRODUTO,ID_CCUSTO,IDENTIFICADOR,QUANTIDADE FROM
+ ESTOQUE WHERE ID_PRODUTO = +#39+ strProduto +#39+ AND ID_CCUSTO =
+#39+ strCCusto + #39+ AND IDENTIFICADOR = +#39+ strIdentificador +#39;

cdsEstoque.Open;


2)
Tente utilizar o fieldByname no lugar do Tfield definido
apague todos para esta fazer este teste e utilize

cds.FieldByname(SeuCampo).TipoDeDaos

Sim é o que estou usando:

if cdsEstoque.FieldByName(quantidade).AsFloat <= 0 then

será que este teucampo Esta sendo carregado pelo Sql ???

Sim, coloque um dbgrid em um form e liguei a um datasorce e
a pesquisa é feita normal com os campos e conteudos... mas
não passa nem a pau ...

faça este teste e nos retorne

ps) Por vafor quem quiser dar sugestões fiquem á vontade
este tópico é público
GOSTEI 0
Marco Salles

Marco Salles

21/02/2012

é como é que esta a propriedade poAllowcommandtext do seu TDataSetProvider ???
GOSTEI 0
Jeremias

Jeremias

21/02/2012

é como é que esta a propriedade poAllowcommandtext do seu TDataSetProvider ???


Tá como True

Eu uso 1 sqlDataSet + 1 DataSetProvider com a propriedade poAllowCommandText = True
pra ligo os CDS ao DataSetPrivider em questão...

GOSTEI 0
Jeremias

Jeremias

21/02/2012

Outro detalhe Marco,

Eu consigo armazenar em variáveis o conteudo de todos os outros campos:

ID, ID_PRODUTO, ID_CCUSTO, IDENTIFICADOR que são dos tipos
INTEGER e VARCHAR

Consquentemente consigo fazer comparações com eles...

Só o campo QUANTIDADE que no meu caso é DECIMAL(12,2) é que dá esse erro aí..

Já tentei pegar ou armazenar como AsFloat, AsCurrency, AsBcd, AsString e nada...

Com AsVariant ele armazena o valor =

No debug ele mostra assim:

cdsEstoque.FielByBame(quantidade).AsVariant = =

Nos outros casos ele mostra:

cdsEstoque.FielByBame(quantidade).AsFloat = delphi exception EconvertError at $9A9F949

Conlcuo então que o problema está com este tipo de dado NUMERIC ou DECIMAL

Me dá uma luz aí pessoal, alguém que já se deparou com estes problemas...

Aliás estou com um probleminha semelhante pra armazenar datas também...

Me Ajuda aí ????
GOSTEI 0
Marco Salles

Marco Salles

21/02/2012

então amigo

passei o seu problema para um outro companheiro (Imex), muito antecioso frofundo conhecedor
Aqui segue o que ele sugeriu


Complicado...
Uma certa curiosidade seria em relação ao tipo do campo (TFmtBCDField, etc) que está sendo atribuido quando o campo é adicionado de forma persistente na Fields Editor.

Não conheço muito a fundo o Firebird, mas acho que também deveria ser verificado o dialeto, pois pelo que vi no firebase.com.br é utilizado Double Precision para precisão entre 10 e 18 se o dialeto for igual a 1. Sei lá, de repente este campo está com um número enorme de casas decimais.

Mas tá complicado mesmo...

obs: não tenho conta, mas não precisa esquentar em relação aos créditos.

Abraço


Agora eu tb vou retornar no quesito Driver ...

Atente-se para algumas perguntas

1) Voce tem o Interbase rodando ???

2) O Seu firebird esta rodando tb ?

3) Voce especificou alguma porta para o Firebird # caso os dois esteja Rodando

4) A questão de compatibilidade não existe para o Firebird 2.1

5) Caso voce estja com o Firebird Rodando e o Interbase parado coloque deixe por
enquato o Driver da Interbase mas coloque no ventor Lib o fbclient.dll
GOSTEI 0
Jeremias

Jeremias

21/02/2012

então amigo

passei o seu problema para um outro companheiro (Imex), muito antecioso frofundo conhecedor
Aqui segue o que ele sugeriu


Complicado...
Uma certa curiosidade seria em relação ao tipo do campo (TFmtBCDField, etc) que está sendo atribuido quando o campo é adicionado de forma persistente na Fields Editor.

Não conheço muito a fundo o Firebird, mas acho que também deveria ser verificado o dialeto, pois pelo que vi no firebase.com.br é utilizado Double Precision para precisão entre 10 e 18 se o dialeto for igual a 1. Sei lá, de repente este campo está com um número enorme de casas decimais.

Mas tá complicado mesmo...

obs: não tenho conta, mas não precisa esquentar em relação aos créditos.

Abraço


Agora eu tb vou retornar no quesito Driver ...

Atente-se para algumas perguntas

1) Voce tem o Interbase rodando ???

2) O Seu firebird esta rodando tb ?

3) Voce especificou alguma porta para o Firebird # caso os dois esteja Rodando

4) A questão de compatibilidade não existe para o Firebird 2.1

5) Caso voce estja com o Firebird Rodando e o Interbase parado coloque deixe por
enquato o Driver da Interbase mas coloque no ventor Lib o fbclient.dll


R1. Não

R2. Sim, somente este com retrocompatibilidade

R3. Não, só fica rodando o FireBird

R5. Estou usando atualmente a GDS32.DLL, vou alterar pra fbclient e fazer os testes, pode ser que
esse seja o problema...

Daqui a pouco te reporto...
GOSTEI 0
Christian Giuliani

Christian Giuliani

21/02/2012

Faça assim:

if cdEstoque.fieldbyname(quantidade).asCurrency <=0 then

Vai resolver. ;)
GOSTEI 0
Jeremias

Jeremias

21/02/2012

Cara já tentei todos os tipos, dá uma lida pra trás...

Mudei a Vendor Lib como o Marco Antonio segeriu pra FBClient... mas tb não funciona...

Agora estou usando Padrão IB com dbexpint e Vendor Lib=Fbclient... continua o erro

Resolvi fazer um teste migrando a base de .GDB pra .FDB, fazendo um backup
em .GBK e o Restore pra .FDB mas também não funcionou...

A pesquisa no banco é feita normal, posso navegar entre os registros e seus conteudos,
e consigo armazenar em variáveis ou comparar o conteudo de todos os campos com tipos
diferentes de NUMERIC ou DECIMAL...

Tem uma CASCA DE BANANA aí no Dbexpress + D7 + Firebird

QUAL É O PULO DO GATO nessas tecnologias ???

Quem saberá me responder ????

Paulista, meu irmão cadê você... se manifesta aí ?

Renato, Romero, Guinther, Luciano, Rodrigo ...

Dá uma ajuda aí pro Aprendiz... hehehe

O Amigo aí do RS também...

Se não, meu irmão, vou pegar meu bonezinho e voltar pra Roça (IBX) que é melhor... hehehe

GOSTEI 0
Marco Salles

Marco Salles

21/02/2012

o cara , teu banco é complicado ??

Se for simples , monte o teu exemplo (D7) vomponentes nativos , e envia para nos que a gente descompacta ele e
fazemos o funcionar .. sem perigo e sem problema

salhamoda@uol.com.br
GOSTEI 0
Christian Giuliani

Christian Giuliani

21/02/2012

Chefe, tenho aqui um sistema rodando e tenho esta comparação (única diferença é que usei < 1 e não <= 0), nela notei também que uso o banco firebird com campos NUMERIC(14,2), você citou o campo ali como sendo DECIMAL, talvez se criar um campo numérico só a nível de teste pra gente eliminar uma possibilidade ja ajudaria.

GOSTEI 0
Jeremias

Jeremias

21/02/2012

o cara , teu banco é complicado ??

Se for simples , monte o teu exemplo (D7) vomponentes nativos , e envia para nos que a gente descompacta ele e
fazemos o funcionar .. sem perigo e sem problema

salhamoda@uol.com.br


Aí parceiro, você apontou o caminho pra solução:

Fiz isso, criei uma aplicação de teste simples com 1 DataModule,
1 form, 1 DataGrid + 1 Source e um Botão pra abrir a pesquisa e
fazer a comparação e passou...

O que significa que o problema está na arquiterura da minha aplicação
principal... ???

O problema é o tecnólogo e não as tecnologias... hehehe...

Vou descobir o que é e te reporto...

Mas veja se pode me ajudar, mas um pouco ?

Uso 1 Data Module principal com 1 SqlDataSet + 1 DataSetProvider + ClientDataSet
pra cada tabela e uso nos forms de cadastro...

Neste mesmo Data Module uso 1 sqlDataSet + 1 DataSetProvider com poAllowCommandText = True
pra pesquisas genéricas onde linko todos os ClientDataSet de pesquisa auxiliares que
são usados de forma unica pelo usuário e não simultânea, assim não há problema de conflitos de pesquisa..

Uso um segundo Data Module pra com 1 SqlDataSet + DataSetProvider + 1 ClientDataSet pra todos os
casos em que preciso de uma pesquisa auxuliar pra dbLookuCombBox

A consulta do ESTOQUE usa a arquitetura de pesquisa genérica do Primeiro Data Module, mas de alguma forma,
depois que abre o CDS ocorre este problema apenas no campo quantidade...

Ainda me intriga, porque aparentemente os componentes estão configurados da mesma forma que no teste...
e convenhamos, que esta é uma comparação normal e corriqueira em qualquer tecnologia...

De qualquer forma, sem a ajuda dos parceiros, eu ainda estaria desnorteado...

valeu chapa,
GOSTEI 0
Marco Salles

Marco Salles

21/02/2012

Mas veja se pode me ajudar, mas um pouco ?

Uso 1 Data Module principal com 1 SqlDataSet + 1 DataSetProvider + ClientDataSet
pra cada tabela e uso nos forms de cadastro...

Primeiro Lugar , voce não é comumm ter muitos dataModulos na Aplicação

Segundo Lugar a maneira correta pouco usual () é separar o clientDataSet do DataModulo do servidor
abrindo perspectiva para uma arquitetura n-tier

terceiro lugar DataSetProvider com poAllowCommandText é uma má prática (Voce deve hj programar para DataSnap)
se voce faz consultas Sql em aplucativos Clientes e tiver uma quantidade deles espalhados por ai qq Alteração
referente a estas consultas tera que recompilar essas cem Aplicações . Portanto não fazemos assim

Para query+dinamica utilizamos esta tecnica , quando for conveniente

http://marcosalles.wordpress.com/?s=query+dinamica


ps) Não entendi o que voce quis dizer com :

onde linko todos os ClientDataSet de pesquisa auxiliares

???

Por fim acho que muitas pesquisas podem ser feitas utilizando o Clone Cursor , pois temos um copia
ds dados em memória sem aumentarmos o seu consumo e ficar independente do seu Ponteiro de Dados

GOSTEI 0
Jeremias

Jeremias

21/02/2012

Mas veja se pode me ajudar, mas um pouco ?

Uso 1 Data Module principal com 1 SqlDataSet + 1 DataSetProvider + ClientDataSet
pra cada tabela e uso nos forms de cadastro...

Primeiro Lugar , voce não é comumm ter muitos dataModulos na Aplicação

Segundo Lugar a maneira correta pouco usual () é separar o clientDataSet do DataModulo do servidor
abrindo perspectiva para uma arquitetura n-tier

terceiro lugar DataSetProvider com poAllowCommandText é uma má prática (Voce deve hj programar para DataSnap)
se voce faz consultas Sql em aplucativos Clientes e tiver uma quantidade deles espalhados por ai qq Alteração
referente a estas consultas tera que recompilar essas cem Aplicações . Portanto não fazemos assim

Para query+dinamica utilizamos esta tecnica , quando for conveniente

http://marcosalles.wordpress.com/?s=query+dinamica


ps) Não entendi o que voce quis dizer com :

onde linko todos os ClientDataSet de pesquisa auxiliares

???

Por fim acho que muitas pesquisas podem ser feitas utilizando o Clone Cursor , pois temos um copia
ds dados em memória sem aumentarmos o seu consumo e ficar independente do seu Ponteiro de Dados



Caro Marco Salles,

Ainda não resolvi a questão acima...

Fiz incansáveis testes... Com Interbase, Firebird, com gds32.dll, com fbclient.dll e o problema continua cara...

A principio achei que era minha estrutura de DM, mas ao aprofundar os testes verifiquei que:

Em tempo de designe, os dados são exibidos normalmente, mas em tempo de execussão, os campos
QUANTIDADE e VLCUSTO que são NUMERIC e DECIMAL ficam com os seguintes conteudos:

Zero quando este é null,
Sinal de igual (=) quando este é 1,00,
Sinal de interrogação (?) quando este é maior que (>) 1,00

Resolvi montar um teste estou te enviando pra você ver ...

Se algum parceiro quiser verificar tb me passa o e-mail que envio o teste...
GOSTEI 0
Jeremias

Jeremias

21/02/2012

Resolvido... UFA !!!

A solução foi apontada pelo nosso amigo MARCO ANTONIO SALLES por e-mail, após envio de um exemplo, conforme segue o texto abaixo:

Usei a terceira alternativa por enquanto e resolveu satisfatoriamente...

Resposta do MARCO SALLES:

Não é de Hj que se sabe da incompatibilidade de campos TFMTBCDField com o Delphi7 . Porém o que foi surpresa para mim
é que a novel de projeto não apresentou problemas e somente em Rum time ..

Qual são as saidas imediatas:

1) migrar para a versão delphi 2010 ( que esta livre deste problema

2) Fazer o Update da versão 7.1 do delphi
http://translate.google.com.br/translate?hl=pt-BR&langpair=en|pt&u=http://edn.embarcadero.com/article/32337

3) Alterar a forma de se escrever este SQL , fazendo um Cast para o Formato que realmente é o campo

Por exemplo , voce escreveu

SELECT E.* ,
A.ID,A.DESCRICAO,PR.ID,PR.MODELO,F.ID,F.R_SOCIAL FROM ESTOQUE E,CCUSTO A, APARELHOS PR,FORNECEDORES F WHERE E.ID_CCUSTO = A.ID AND E.ID_PRODUTO = PR.ID AND E.ID_FORNECEDOR = F.ID

O que tem que ser feito neste caso é adicionar todos os campos manualementes e fazendo o Cast

Exemplo

SELECT E.ID , CAST(E.QUANTIDADE AS Float) AS QUANTIDADE , CAST(VLCUSTO AS FLOAT) AS VLCUSTO , E.DEMAIS CAMPOS , etc...
A.ID,A.DESCRICAO,PR.ID,PR.MODELO,F.ID,F.R_SOCIAL FROM ESTOQUE E,CCUSTO A, APARELHOS PR,FORNECEDORES F WHERE E.ID_CCUSTO = A.ID AND E.ID_PRODUTO = PR.ID AND E.ID_FORNECEDOR = F.ID

GOSTEI 0
POSTAR