Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 1 of 1 total
Thread Error in TEdbDataSet.Locate
Mon, Apr 13 2015 5:51 PMPermanent Link

macc2010

Hello,

When I have a table with one field of type date and indexed by this field, if I do TEdbtable.Locate with a TDate variable value I get the following error : ElevateDB Error #1011 An error occurred with the value 42105 (A conversion error occurred with the value 42105).

Here there is an easy sample to reproduce the problem :

// I have a form with the following components :
  Db1: TEDBDatabase;
  Tb1: TEDBTable;
  Session1: TEDBSession;
// and this is the FormCreate for the above form :
procedure TForm1.FormCreate(Sender: TObject);
var
L : TStringList;
dDate : TDate;
begin
Session1.SessionName := 'Session1';
Session1.SessionType := stLocal;
Session1.LoginUser := 'Administrator';
Session1.LoginPassword := 'EDBDefault';
Session1.LocalConfigPath := ExtractFileDir( Application.ExeName );
edbcomps.Engine.ConfigPath := Session1.LocalConfigPath;
Session1.Open;
Db1.Database := 'TEST';
Db1.DatabaseName := Db1.Database;
Db1.SessionName := Session1.SessionName;
Tb1.DatabaseName := Db1.DatabaseName;
Tb1.TableName := 'TESTDATE';
Tb1.SessionName := Session1.SessionName;
L := TStringList.Create;
try
  Session1.GetDatabases( L );
  if L.IndexOf( Db1.Database ) = -1 then
    Session1.Execute( 'CREATE DATABASE "' + Db1.Database + '"  PATH ' + QuotedStr( Session1.LocalConfigPath ) );
  Db1.Open;
  L.Clear;
  Session1.GetTableNames( Db1.Database, L );
  if L.IndexOf( Tb1.TableName ) = -1 then
  begin
    Db1.Execute( 'CREATE TABLE "' + Tb1.TableName + '" ( "DATEFIELD" DATE )' );
    Db1.Execute( 'CREATE INDEX "iDate" ON "' + Tb1.TableName + '" ("DATEFIELD")' );
  end;
finally
  L.Free;
end;
Tb1.Open;
Tb1.IndexName := 'iDate';
dDate := Date;
// test FindKey
if not Tb1.FindKey( [ dDate ] ) then
begin
  Tb1.Append;
  Tb1.FieldByName( 'DATEFIELD' ).Value := dDate;
  Tb1.Post;
end;
// test FindKey again
Tb1.FindKey( [ dDate ] ) ;
// test Locate -------> THIS WILL RAISE EXCEPTION : ElevateDB Error #1011 An error occurred with the value   
// 42105 (A conversion error occurred with the value 42105)
Tb1.Locate( 'DATEFIELD', dDate, [] );
end;

Initially, the problem is in the declaration of the dDate variable. If you declare the dDate variable as TDate, an exception is thrown, but if you declare the dDate variable as TDateTime, all is ok.

I think that the problem is that the VarType( dFecha ) = varDouble when you declare the dDate variable as TDate. But if you declare the dDate variable as TDateTime, VarType( dFecha ) = varDate. The problem is that TEDBValue.SetAsVariant does not have in account that you can use a variable of type TDate as a parameter of a Locate, it only have in account the type of the variant passed value and it will raise an exception, because is treating this value as a double value and not as a TDate value. I think that the solution could be to correct the procedure TEDBValue.SetAsVariant having in account that if VarType of value passed is varDouble and DataType is TYPE_DATE call to AsDateTime:=TDateTime(Value).  It is a problem in the elevatedb sources, and it is easy to correct.

Another solution is to take in account it in the procedure SetAsDouble, doing the following modification :

procedure TEDBValue.SetAsDouble(const Value: Double);
var
 TempLargeInt: Int64;
begin
 SetNull(False);
 case FDataType of
    TYPE_FLOAT:
.............
    // take in account a TDate value <--- THIS IS NEW
    TYPE_DATE :
        SetInteger(NativeDateToDate(TDateTime(Value)));
end;

Or in the TEDBValue.SetAsVariant when you :

case VarType(Value) of
....
....
varSingle:
   AsDouble:=Double(Value);
varDouble :
   // CORRECT FOR TDate value assigned to a variant and the field is DATE
   if FDataType = TYPE_DATE then
      AsDateTime:=TDateTime(Value)
   else
       AsDouble:=Double(Value);
.......
........
end;

Both solutions does work, but you are the expert, not me.

Thank you and best regards.
Image