【问题标题】:'' is not valid floating point value delphi'' 不是有效的浮点值 delphi
【发布时间】:2013-11-29 01:36:03
【问题描述】:

抛出错误信息

` qConsulta2 := TQuery.Create(Application);
  qConsulta2.DatabaseName := 'BaseDato';
  qConsulta2.SQL.Text := 'select VALOR from PARAMETRO where codigoPARAMETRO  = ''IVA'' ';
  qConsulta2.open;
  qCompraDetalle.FieldByName('PORCENTAJE_IVA').AsFloat:=        qConsulta2.fieldbyname('valor').asfloat;
  qConsulta2.close;
  qConsulta2.free `

这让我执行了这个错误,不知道为什么,在此非常感谢您的时间和帮助。请原谅我的英语不好。

【问题讨论】:

  • 2013 年还在使用 BDE 吗?哇...

标签: delphi floating-point


【解决方案1】:

您的问题在于qConsulta2.fieldbyname('valor').asfloat 根据我的测试,如果 VALOR 列是数据库表中的 text 或 varchar 并且它包含 Null 或零长度字符串,则会发生错误。

我的测试涉及在 MSAccess 数据库中创建一个包含 VALOR_TEXT 和 VALOR_FLOAT 列的表。 VALOR_TEXT 定义为文本,VALOR_FLOAT 定义为双精度。我为 4 个测试用例编写代码,2 个说明错误(Case1 和 Case2),2 个提供解决方案(Case 3 和 Case4)。下面提供了代码。

procedure TForm1.Case1;
var
  f : double;
begin
  db.ExecSQL('delete from PARAMETRO');
  db.ExecSQL('insert into PARAMETRO (codigoPARAMETRO) values(''IVT'')');
// VALOR_FLOAT and VALOR_TEXT are null
  qConsulta2.SQL.Text := 'select * from PARAMETRO';
  qConsulta2.Open();
  f := qConsulta2.FieldByName('VALOR_FLOAT').AsFloat;
  ShowMessage('From Float '+FloatToStr(f));
  f := qConsulta2.FieldByName('VALOR_TEXT').AsFloat;
  ShowMessage('From Text '+FloatToStr(f));
end;

procedure TForm1.Case2;
var
  f : double;
begin
  db.ExecSQL('delete from PARAMETRO');
  db.ExecSQL('insert into PARAMETRO (codigoPARAMETRO,VALOR_TEXT) values(''IVT'','''')');
// VALOR_FLOAT is null and VALOR_TEXT is '' (zero length string)
  qConsulta2.SQL.Text := 'select * from PARAMETRO';
  qConsulta2.Open();
  f := qConsulta2.FieldByName('VALOR_FLOAT').AsFloat;
  ShowMessage('From Float '+FloatToStr(f));
  f := qConsulta2.FieldByName('VALOR_TEXT').AsFloat;
  ShowMessage('From Text '+FloatToStr(f));
end;

Case3 直接适用于修复您的代码。通过获取 AsVariant 数据,NullStrictConvert := false 将允许将 Null 值转换为浮点、整数或字符串,而不会出现异常。

procedure TForm1.Case3;
var
  f : double;
begin
  NullStrictConvert := false;
  db.ExecSQL('delete from PARAMETRO');
  db.ExecSQL('insert into PARAMETRO (codigoPARAMETRO) values(''IVT'')');
// VALOR_FLOAT and VALOR_TEXT are null
  qConsulta2.SQL.Text := 'select * from PARAMETRO';
  qConsulta2.Open();
  f := qConsulta2.FieldByName('VALOR_FLOAT').AsFloat;
  ShowMessage('From Float '+FloatToStr(f));
  f := qConsulta2.FieldByName('VALOR_TEXT').AsVariant;
  ShowMessage('From Text '+FloatToStr(f));
end;

Case4 提供了一种避免数据转换的方法,只要源列和目标列的类型相同。如果它们不是同一类型,仍然会出现数据转换错误。

procedure TForm1.Case4;
var
  f : double;
begin
  NullStrictConvert := false;
  db.ExecSQL('delete from PARAMETRO');
  db.ExecSQL('insert into PARAMETRO (codigoPARAMETRO) values(''IVT'')');
// VALOR_FLOAT and VALOR_TEXT are null
  qConsulta2.SQL.Text := 'select * from PARAMETRO';
  qConsulta2.Open();
  f := qConsulta2['VALOR_FLOAT'];
  ShowMessage('From Float '+FloatToStr(f));
  f := qConsulta2['VALOR_TEXT'];
  ShowMessage('From Text '+FloatToStr(f));
  // avoid data conversion
  qCompraDetalle.Open();
  qCompraDetalle.Append;
  qCompraDetalle['PORCENTAJE_IVA'] := qConsulta2['VALOR_TEXT'];
  qCompraDetalle.Post;
end;

【讨论】:

    【解决方案2】:

    确保 qConsulta2.fieldbyname('valor').asfloat 不为空。

    【讨论】:

    • 空,我猜你的意思是NULL?在 Null 浮点字段上调用 ​​AsFloat 将返回 0,而不是错误。
    • rkawano 如何确保不为空? FieldByName 和我在事件 FormCreate DateSeparator: = '/';小数分隔符:=; '。 LongDateFormat: = 'dd / mm / yyyy';千位分隔符:= '';时间分隔符: = ':';但它一直抛出错误
    • 直接在您的数据库上运行此查询:SELECT * FROM Parametro WHERE Valor IS NULL OR Valor = '' 如果任何记录为空,它将显示给您。
    • @JeissonNiño 打开帮助并搜索“空”字 - docwiki.embarcadero.com/Libraries/XE2/en/…
    【解决方案3】:

    您必须检查您的查询是否确实返回了记录:

    qConsulta2 := TQuery.Create(Application);
    try
      qConsulta2.DatabaseName := 'BaseDato';
      qConsulta2.SQL.Text := 'select VALOR from PARAMETRO where codigoPARAMETRO  = ''IVA'' ';
      qConsulta2.open;
      if not qConsulta2.EOF then  
       qCompraDetalle.FieldByName('PORCENTAJE_IVA').AsFloat:= qConsulta2.fieldbyname('valor').asfloat;
      qConsulta2.close;
    finally 
      qConsulta2.free 
    end;
    

    或者,如果您想确保始终返回一条记录,请使用 SQL COALESCE 命令:

    qConsulta2 := TQuery.Create(Application);
    try
      qConsulta2.DatabaseName := 'BaseDato';
      qConsulta2.SQL.Text := 'select COALESCE(VALOR, 0) AS valor from PARAMETRO where codigoPARAMETRO  = ''IVA'' ';
      qConsulta2.open;
      qCompraDetalle.FieldByName('PORCENTAJE_IVA').AsFloat:= qConsulta2.fieldbyname('valor').asfloat;
      qConsulta2.close;
    finally 
      qConsulta2.free 
    end;
    

    更新

    在这里猜测一下,因为您没有提供数据库详细信息:如果 PARAMETRO 表中的 VALOR 字段实际上是 Varchar 类型,那么您可以使用空字符串而不是 NULL

    qConsulta2 := TQuery.Create(Application);
    try
      qConsulta2.DatabaseName := 'BaseDato';
      qConsulta2.SQL.Text := 'select VALOR from PARAMETRO where codigoPARAMETRO  = ''IVA'' ';
      qConsulta2.open;
      if qConsulta2.FieldByName('VALOR').AsString <> '' then  
       qCompraDetalle.FieldByName('PORCENTAJE_IVA').AsFloat:= qConsulta2.fieldbyname('valor').asfloat;
      qConsulta2.close;
    finally 
      qConsulta2.free 
    end;
    

    【讨论】:

    • 是的,OP应该检查空数据集,但即使它是空的,它也会返回0,而不是错误。
    • @MarcusAdams,不,它会 AV,因为 qConsulta2.fieldbyname('valor') 将为零,因为没有返回记录集?
    • 我猜这可能取决于您特定 TQuery 组件的实现,但它应该只是 NULL,而不是引发 AV。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-19
    • 2021-05-10
    • 2021-12-26
    • 1970-01-01
    相关资源
    最近更新 更多