数据库结果的变量结构

时间:2013-03-22 14:05:05

标签: sql delphi

很多时候,当我们查询数据库时,我们只需要一个带varchar的列。 所以我做了一个很好的函数来查询数据库并将结果放在一个字符串列表中:

function Getdatatostringlist(sqlcomponent, sqlquery: string): TStringlist;

我现在正在寻找的是基本相同的功能,但对于具有多列的结果,您事先并不知道数据的类型,无论是varchar,int,datetime。

这里使用什么样的数据结构。

我想要的原因是我尝试不使用开放数据集。我更喜欢将所有结果提取到临时结构中,关闭数据集并处理结果。


在Kobiks回复关于在内存数据集中使用后,我想出了以下内容,它可以快速组合起来测试这个概念:

procedure TForm1.Button2Click(Sender: TObject);
var
  MyDataSet : TAdoDataSet;
begin
 MyDataSet := GetDataToDataSet('SELECT naam FROM user WHERE userid = 1', ADOConnection1);
 try
   Form1.Caption := MyDataSet.FieldByName('naam').AsString;
 finally
   MyDataSet.free;
 end;
end;

function TForm1.GetDataToDataSet(sSql: string; AdoConnection: TADOConnection): TAdoDataSet;
begin
  Result := TAdoDataSet.Create(nil);
  Result.LockType := ltBatchOptimistic;
  Result.Connection := AdoConnection;
  Result.CommandText :=  sSql;
  Result.Open;
  Result.Connection := nil;
end;

我认为这是建立起来的东西。

3 个答案:

答案 0 :(得分:7)

您应该使用任何断开连接的内存TDataSet后代,例如TClientDataSet

不要试图通过在一些新的“Variant”结构中存储记录集来重新发明轮子。 TClientDataSet已包含操作“临时”数据结构所需的所有功能。

以下是创建TClientDataSet结构的方法:

cds.FieldDefs.Add('id', ftInteger);
cds.FieldDefs.Add('name', ftString, 100);
// ...
// create it
cds.CreateDataSet; 
// add some data records
cds.AppendRecord([1, 'Foo']);
cds.AppendRecord([2, 'Bar']);

许多TDataSets都可以用作内存(客户端)数据集,具体取决于提供商和LockType,例如TADODataSet LockType=ltBatchOptimistic可以获取结果集从服务器,然后保持断开连接。

答案 1 :(得分:3)

为了与Excel交换数据,这种结构很有用,可能对其他用途有用。

Function GetDatasetasDynArray(Ads: TDataset; WithHeader: Boolean = true): Variant;
// 20130118 by Thomas Wassermann
var
  i, x, y: Integer;
  Fields: Array of Integer;
begin
  x := 0;
  y := Ads.RecordCount;
  if WithHeader then
    inc(y);
  SetLength(Fields, Ads.FieldCount);
  for i := 0 to Ads.FieldCount - 1 do
    if Ads.Fields[i].Visible then
    begin
      Fields[x] := i;
      inc(x);
    end;
  SetLength(Fields, x);
  Result := VarArrayCreate([0, y - 1 , 0, length(Fields) - 1], VarVariant);
  y := 0;
  if WithHeader then
  begin
    for i := Low(Fields) to High(Fields) do
    begin
      Result[y, i] := Ads.Fields[Fields[i]].DisplayLabel;
    end;
    inc(y);
  end;
  try
    Ads.DisableControls;
    Ads.First;
    while not Ads.EOF do
    begin
      for i := Low(Fields) to High(Fields) do
      begin
        Result[y, i] := Ads.Fields[Fields[i]].Value;
      end;
      Ads.Next;
      inc(y);
    end;
  finally
    Ads.EnableControls;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 DynArray:Variant;
begin

   DynArray := GetDatasetasDynArray(Adodataset1,true);
   //DynArray[0,x] Header or First row
   //DynArray[1,x] First row or SecondRow
   Excel.Range.Value := DynArray;
end;

答案 2 :(得分:1)

为什么不喜欢使用开放数据集?它们通常不会阻止服务器。将数据集中的数据复制到您想要的任何内容是额外的开销,这很可能是不必要的。

数据集提供您想要的功能:具有可变列和行的矩阵。

编辑:但是,如果您经常迭代数据集,则应考虑创建一个包含相关信息的类,然后将数据复制到通用列表,字典,树或任何您需要的快速查找结构。

当然,您可以考虑构建一些智能的东西,它可以像数据集一样灵活但是:一般情况越多,性能越差(通常)。