1

很多时候,当我们查询数据库时,我们只需要一列带有 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;

我认为这是可以建立的。

4

3 回答 3

7

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

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

以下是创建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']);

许多 TDataSet 能够根据提供者用作内存(客户端)数据集LockType,例如TADODataSetwithLockType=ltBatchOptimistic可以从服务器获取结果集,然后保持断开连接。

于 2013-03-22T14:12:20.567 回答
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;
于 2013-03-22T14:18:30.387 回答
1

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

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

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

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

于 2013-03-22T14:10:11.433 回答