How Firebird uses GUID fields to operate in Delphi

There is no special GUID type field in FireBird database. The field type used is: Char(16) OCTETS can store GUID;

In Delphi, use FireDAC FdQuery to open the table with this field. The corresponding field type is: TBytesField; forcibly changing this field to a TGUIDField type field, opening the table will cause an exception of type mismatch; similarly, the corresponding field in ClientDataSet The field type is also TBytesField, and cannot be forced to be a field of TGUIDField type;

 

If there is a field of type TGUIDField in a ClientDataSet, such as the field name: ID, if you perform a Locate search on this field, there will be no exception, but it cannot be located. If you use FindKey, you can locate it, but you must first specify that this field is the Index field. code show as below:

function VarFromGuid(const aGuid: TGuid): Variant;
 var
    Ptr: Pointer;
 begin
    Result := VarArrayCreate( [1, Sizeof(aGuid)], varByte);
    Ptr := VarArrayLock(Result);
    try
      Move(aGuid, Ptr^, Sizeof(aGuid));
    finally
     VarArrayUnlock(Result);
   end;
 end;

The above function converts GUID to Variant, because the parameter type required by DataSet.Locate is variant.

procedure TForm1.Button7Click(Sender: TObject);
var
  G: TGUID;
  S: string;
  V: Variant;
begin
  //这里的 ID 字段是 TGUIDField 类型
  S := Edit2.Text;
  G := StringToGUID(S);
  V := VarFromGUID(G);

  with ClientDataSet2 do
  begin
    Locate('ID',varArrayOf([V]) , []); //定位不到。但执行不会出异常。
    //ClientDataSet2.FindKey([S]);  //可以定位到。
  end;
end;

-----------------------------------

If the field type of ClientDataSet is TBytesField, the Locate('ID',varArrayOf([V]), []); method cannot be executed, and the runtime will prompt for unsupported types.

But for FireDAC, if FdMemTable has a field of TBytesField type, you can execute the Locate('ID',varArrayOf([V]), []) method to find it successfully.

For the TBytesField field of ClientDataSet, execute FindKey method to successfully locate. code show as below:

procedure TForm1.Button5Click(Sender: TObject);
var
  G: TGUID;
  S: string;
  V: Variant;
begin
  //这里的 M_ID 字段是 TBytesField 类型,对应的是 FireBird 里面的 Char(16) OCTETS 类型字段
  S := '{F3E75FED-5C47-439D-A5BE-913EF9457577}';
  G := StringToGUID(S);
  V := VarFromGUID(G);

  { 以下代码对 FdMemTable1 进行 Locate 成功。
  FdQuery1.Open();
  FDMemTable1.CopyDataSet(ClientDataSet1);

  DataSource1.DataSet := FDMemTable1;
  with FDMemTable1 do
  begin
    Locate('M_ID', varArrayOf([VarFromGuid(G)]), []);
  end;
  }

  with ClientDataSet1 do
  begin
    //Locate('M_ID',varArrayOf([V]) , []); // 会出现异常
    FindKey([V]);
  end;

end;

 

Corresponding TBytesField, directly write GUID successfully:

procedure TForm1.Button3Click(Sender: TObject);
begin
  //M_ID 是 TBytesField 类型的字段,写入成功
  with ClientDataSet1 do
  begin
    Insert;
    FieldByName('M_ID').AsGuid := Self.GetGUID;
    Post;
  end;
end;

 

 

also:

If it is FdMemTable , the same TBytesField field can be successfully located by using the above Locate method.

Therefore, FdMemTable is indeed better than ClientDataSet.

 

SQL query:

Query the GUID field in Firebird: select * from MATERIAL where M_ID=:MID

Use FdQuery control, the test is successful:

procedure TForm1.Button4Click(Sender: TObject);
begin
  //能够成功搜索到正确记录
  with FdQuery2 do
  begin
    Close;
    Params[0].AsGUID := StringToGUID('{F3E75FED-5C47-439D-A5BE-913EF9457577}');
    Open;
    DataSource1.DataSet := FdQuery2;
  end;
end;

 to sum up:

A 16-byte OCTETS type field can be used to store GUIDs in the Firebird database, which saves a lot of space than storing GUIDs in string format; string format requires 36 bytes.

The field type corresponding to Delphi's DataSet is TBytesField. You can use Field.AsGUID to write data of type TGUID during runtime, and the submission is successful.

For FdQuery and FdMemTable, the above TBytesField field can be Locate, and the GUID parameter needs to be converted to Variant.

For ClientDataSet, an exception will occur when Locate the TBytesField field; automatic Locate on TGUIDField will not cause an exception but cannot be located. However, the FindKey method was used to locate and succeeded. So corresponding to the GUID field of the Firebird database, ClientDataSet can use FindKey. It should be noted that the field of DataSet.FindKey must be an index field.

 

Guess you like

Origin blog.csdn.net/pcplayer/article/details/108480898