Problemas com o DbExpress
Boa tarde pessoal,
Estou desenvolvendo uma única aplicação na qual eu possa usar o banco de dados Interbase ou o Sql Server e assim, estou usando o dbExpress para fazer isso mas estou com seguinte problema:
Tenho em uma tabela um campo denominado PercIrf com a seguinte definição Numeric(5,2) , para armazer valores em percentuais. E essa tabela foi criada no Interbase e no Sql Server.
Porem quando estou em meu aplicativo usando o SqlServer funciona normalmente, mas quando abroe abro a Tabela em questão me é retornado o seguinte erro:
SimpleDataSet: Type mysmatch for field ´PercUrg´, expecting:BCD actual:FmtBcdField.
Alguém pode me ajudar ??????
Estou desenvolvendo uma única aplicação na qual eu possa usar o banco de dados Interbase ou o Sql Server e assim, estou usando o dbExpress para fazer isso mas estou com seguinte problema:
Tenho em uma tabela um campo denominado PercIrf com a seguinte definição Numeric(5,2) , para armazer valores em percentuais. E essa tabela foi criada no Interbase e no Sql Server.
Porem quando estou em meu aplicativo usando o SqlServer funciona normalmente, mas quando abroe abro a Tabela em questão me é retornado o seguinte erro:
SimpleDataSet: Type mysmatch for field ´PercUrg´, expecting:BCD actual:FmtBcdField.
Alguém pode me ajudar ??????
Arllain
Curtidas 0
Respostas
Gameiro
20/07/2005
Os nomes dos campos são diferentes?
denominado PercIrf com a seguinte definição Numeric(5,2)
Type mysmatch for field ´PercUrg´, expecting:BCD actual:FmtBcdField
GOSTEI 0
Oswaldosaraujo
20/07/2005
O FB/IB DBExpress não funciona com valores assim, eu coloquei Numeric 10,4 e funciona ok, se vc colocar 10,2 tb funciona...Eu tive o mesmo problema com 8,4 que era o que eu usava...Vc não terá problemas com o MS-SQL...
GOSTEI 0
Bon Jovi
20/07/2005
Já passei tb por esses problemas, IB/FB+Delphi são chatos mesmo nos tipos numéricos.
Essas dicas podem funcionar nesse caso, mas tem situações entre outros bancos que a coisa complica mais. Coisas como o TField de um campo varchar de um banco vir como TWideStringField, outro vir como TStringField, e até TMemoField dependendo do driver utilizado. Numa situação dessas eu acho melhor não instancionar TFields em tempo de design, assim fica mais flexível. Só não se deve esquecer de setar os providerflags em runtime.. Exemplo simples:
Essas dicas podem funcionar nesse caso, mas tem situações entre outros bancos que a coisa complica mais. Coisas como o TField de um campo varchar de um banco vir como TWideStringField, outro vir como TStringField, e até TMemoField dependendo do driver utilizado. Numa situação dessas eu acho melhor não instancionar TFields em tempo de design, assim fica mais flexível. Só não se deve esquecer de setar os providerflags em runtime.. Exemplo simples:
procedure TForm1.ClientDataSet1AfterOpen(DataSet: TDataSet); var i: integer; begin for i := 0 to DataSet.FieldCount - 1 do begin if AnsiUpperCase(DataSet.Fields[i].Name) = ´ID_CLIENTE´ then DataSet.Fields[i].ProviderFlags := [pfInUpdate,pfInWhere,pfInKey] else if AnsiUpperCase(DataSet.Fields[i].Name) = ´CALCULO´ then DataSet.Fields[i].ProviderFlags := [] else DataSet.Fields[i].ProviderFlags := [pfInUpdate]; end; end; procedure TForm1.SQLDataSet1AfterOpen(DataSet: TDataSet); begin ClientDataSet1AfterOpen(DataSet); end;
GOSTEI 0
Bon Jovi
20/07/2005
Corrigindo, ao inves de .Name é .FieldName.
procedure TForm1.ClientDataSet1AfterOpen(DataSet: TDataSet); var i: integer; begin for i := 0 to DataSet.FieldCount - 1 do begin if AnsiUpperCase(DataSet.Fields[i].FieldName) = ´ID_CLIENTE´ then DataSet.Fields[i].ProviderFlags := [pfInUpdate,pfInWhere,pfInKey] else if AnsiUpperCase(DataSet.Fields[i].FieldName) = ´CALCULO´ then DataSet.Fields[i].ProviderFlags := [] else DataSet.Fields[i].ProviderFlags := [pfInUpdate]; end; end; procedure TForm1.SQLDataSet1AfterOpen(DataSet: TDataSet); begin ClientDataSet1AfterOpen(DataSet); end;
GOSTEI 0
Arllain
20/07/2005
Galera,
já tentei de tudo e ainda não consegui resolver meu problema. Já troque no banco o tamanha do campo para Numeric(10,4).
Estou tentando instanciar os TFields da query no runtime, mas quando eu abro diz que o campo não foi encontrado.
Se alguém souber como faço pra instanciar no runtime me digam.
Estou fazendo assim:
curValUrg.Value := fmConv.sdsConv.FieldByName(´VALURG´).AsFloat;
Valeu.
já tentei de tudo e ainda não consegui resolver meu problema. Já troque no banco o tamanha do campo para Numeric(10,4).
Estou tentando instanciar os TFields da query no runtime, mas quando eu abro diz que o campo não foi encontrado.
Se alguém souber como faço pra instanciar no runtime me digam.
Estou fazendo assim:
curValUrg.Value := fmConv.sdsConv.FieldByName(´VALURG´).AsFloat;
Valeu.
GOSTEI 0
Arllain
20/07/2005
Galera,
já tentei de tudo e ainda não consegui resolver meu problema. Já troque no banco o tamanha do campo para Numeric(10,4).
Estou tentando instanciar os TFields da query no runtime, mas quando eu abro diz que o campo não foi encontrado.
Se alguém souber como faço pra instanciar no runtime me digam.
Estou fazendo assim:
curValUrg.Value := fmConv.sdsConv.FieldByName(´VALURG´).AsFloat;
Valeu.
já tentei de tudo e ainda não consegui resolver meu problema. Já troque no banco o tamanha do campo para Numeric(10,4).
Estou tentando instanciar os TFields da query no runtime, mas quando eu abro diz que o campo não foi encontrado.
Se alguém souber como faço pra instanciar no runtime me digam.
Estou fazendo assim:
curValUrg.Value := fmConv.sdsConv.FieldByName(´VALURG´).AsFloat;
Valeu.
GOSTEI 0
Bon Jovi
20/07/2005
´Estou tentando instanciar os TFields da query no runtime´
Não precisa vc instanciar, após chamar o método Open do DataSet o Delphi já instancia normalmente de acordo com os campos da query. Daí basta vc acessar via FieldByName.
Nao tem pq dar erro de campo nao encontrado por nao ter instanciado em design. Limpe tb o FieldDefs, não só os TFields. Na pior das hipóteses, jogue fora o dataset e crie um novo do zero.
GOSTEI 0
Arllain
20/07/2005
Galera,
Obrigado pelas dicas pois eu consegui resolver o probleminha que tava tendo.
Mas agora surgiu outro problema que é quando to trabalhando com campos do tipo Data, dá um erro dizendo o seguinte:
DbExpress Error : Invalid field Type.
Já tentei colocar o tipo do parametro como : ftTimeStamp, ftDate, ftDateTime. E ele continua dando erro
estou passando a data assim no meu código:
sdsPes.DataSet.ParamByName(´DATEVAL´).AsDate := dtpDateVal.Date;
sdsPes = SimpleDataSet
dtpDateVal = DateTimePicker.
Galera desculpa pelas perguntas bobas, mas é que sou novo em DbExpress e é meu primeiro contato com ele.
Valeu !!!
Obrigado pelas dicas pois eu consegui resolver o probleminha que tava tendo.
Mas agora surgiu outro problema que é quando to trabalhando com campos do tipo Data, dá um erro dizendo o seguinte:
DbExpress Error : Invalid field Type.
Já tentei colocar o tipo do parametro como : ftTimeStamp, ftDate, ftDateTime. E ele continua dando erro
estou passando a data assim no meu código:
sdsPes.DataSet.ParamByName(´DATEVAL´).AsDate := dtpDateVal.Date;
sdsPes = SimpleDataSet
dtpDateVal = DateTimePicker.
Galera desculpa pelas perguntas bobas, mas é que sou novo em DbExpress e é meu primeiro contato com ele.
Valeu !!!
GOSTEI 0
Bon Jovi
20/07/2005
pra campo do tipo TIMESTAMP deve ser usado mesmo DataType = ftTimeStamp e pra DATE ftDate.
E ao invés de ´AsDate´ ou ´AsDateTime´ tente usar ´Value´ pra atribuir o valor ao parametro.
E ao invés de ´AsDate´ ou ´AsDateTime´ tente usar ´Value´ pra atribuir o valor ao parametro.
GOSTEI 0
Arllain
20/07/2005
Grande Bon Jovi
Valeu cara pela ajuda, eu passei a instanciar os Tfields no runtime daí deu tudo certo.
Mas agora to com outro problema que é qdo eu adiciono um campo calculado no meu simpledataset ele não encontra o campo da tabela que eu uso para fazer o cálculo pro campo calculado receber.
Vc sabe o q pode ser? Ou sabe me dizer onde eu possa encontrar um tutorial, manual ou alguma coisa sobre dbExpress? Para que eu n tenha que ficar pedindo ajuda a vc o tempo todo.
O codigo é o seguinte:
procedure TfmProc.sdsProcCalcFields(DataSet: TDataSet);
begin
if Length(Trim(sdsProc.FieldByName(´CODPROC´).AsString)) > 7 then
sdsProc.FieldByName(´CODIGO´).AsString :=
Copy(sdsProc.FieldByName(´CODPROC´).AsString,1,2) + ´.´ +
Copy(sdsProc.FieldByName(´CODPROC´).AsString,3,2) + ´.´ +
Copy(sdsProc.FieldByName(´CODPROC´).AsString,5,3) + ´-´ +
Copy(sdsProc.FieldByName(´CODPROC´).AsString,8,1)
else
sdsProc.FieldByName(´CODIGO´).AsString :=
Copy(sdsProc.FieldByName(´CODPROC´).AsString,1,2) + ´.´ +
Copy(sdsProc.FieldByName(´CODPROC´).AsString,3,2) + ´.´ +
Copy(sdsProc.FieldByName(´CODPROC´).AsString,5,3);
end;
onde CODIGO é o meu campo calculado que recebe o campo da tabela CODRPROC em um formato dependendo to tamanho do CODRPROC.
Valeu
Valeu cara pela ajuda, eu passei a instanciar os Tfields no runtime daí deu tudo certo.
Mas agora to com outro problema que é qdo eu adiciono um campo calculado no meu simpledataset ele não encontra o campo da tabela que eu uso para fazer o cálculo pro campo calculado receber.
Vc sabe o q pode ser? Ou sabe me dizer onde eu possa encontrar um tutorial, manual ou alguma coisa sobre dbExpress? Para que eu n tenha que ficar pedindo ajuda a vc o tempo todo.
O codigo é o seguinte:
procedure TfmProc.sdsProcCalcFields(DataSet: TDataSet);
begin
if Length(Trim(sdsProc.FieldByName(´CODPROC´).AsString)) > 7 then
sdsProc.FieldByName(´CODIGO´).AsString :=
Copy(sdsProc.FieldByName(´CODPROC´).AsString,1,2) + ´.´ +
Copy(sdsProc.FieldByName(´CODPROC´).AsString,3,2) + ´.´ +
Copy(sdsProc.FieldByName(´CODPROC´).AsString,5,3) + ´-´ +
Copy(sdsProc.FieldByName(´CODPROC´).AsString,8,1)
else
sdsProc.FieldByName(´CODIGO´).AsString :=
Copy(sdsProc.FieldByName(´CODPROC´).AsString,1,2) + ´.´ +
Copy(sdsProc.FieldByName(´CODPROC´).AsString,3,2) + ´.´ +
Copy(sdsProc.FieldByName(´CODPROC´).AsString,5,3);
end;
onde CODIGO é o meu campo calculado que recebe o campo da tabela CODRPROC em um formato dependendo to tamanho do CODRPROC.
Valeu
GOSTEI 0
Bon Jovi
20/07/2005
Não costumo trabalhar muito com campo calculado no DataSet, e dentro dessa sua questão não sei se seria possível usa-lo facilmente. Prefiro calcular tudo direto na query ou trabalhar no evento OnGetText do TField qdo for coisas bem leves.
Ex. com OnGetText:
Ex. na query:
Poderia usar no lugar do if do Delphi o CASE WHEN da SQL, no lugar de Copy usar SUBSTRING, e por aí vai... Não sei se o Interbase suporta essas operações padrões.
Ex. com OnGetText:
... private procedure CODPROCGetText(Sender: TField; var Text: String; DisplayText: Boolean); ... ClientDataSet1.Open; ClientDataSet1.FieldByName(´CODPROC´).OnGetText := CODPROCGetText; ... procedure TForm1.CODPROCGetText(Sender: TField; var Text: String; DisplayText: Boolean); begin if Sender.AsString = ´teste´ then Text := ´exibicao alterada!´ else Text := Sender.AsString; end;
Ex. na query:
Poderia usar no lugar do if do Delphi o CASE WHEN da SQL, no lugar de Copy usar SUBSTRING, e por aí vai... Não sei se o Interbase suporta essas operações padrões.
GOSTEI 0
Arllain
20/07/2005
Cara obrigado pela dica do evento OnGetText, consegui fazer o que eu queria.
Valeu
Valeu
GOSTEI 0