GARANTIR DESCONTO

Fórum Problemas com o DbExpress #288883

20/07/2005

0

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 ??????


Arllain

Arllain

Responder

Posts

20/07/2005

Gameiro

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



Responder

Gostei + 0

20/07/2005

Oswaldosaraujo

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


Responder

Gostei + 0

20/07/2005

Bon Jovi

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:

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;



Responder

Gostei + 0

20/07/2005

Bon Jovi

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;



Responder

Gostei + 0

27/07/2005

Arllain

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.


Responder

Gostei + 0

27/07/2005

Arllain

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.


Responder

Gostei + 0

27/07/2005

Bon Jovi

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


Responder

Gostei + 0

29/07/2005

Arllain

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 !!!


Responder

Gostei + 0

29/07/2005

Bon Jovi

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.


Responder

Gostei + 0

02/08/2005

Arllain

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


Responder

Gostei + 0

03/08/2005

Bon Jovi

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


Responder

Gostei + 0

03/08/2005

Arllain

Cara obrigado pela dica do evento OnGetText, consegui fazer o que eu queria.

Valeu


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar