1

多くの場合、データベースにクエリを実行するときに必要なのは、varcharを含む1つの列だけです。そこで、データベースにクエリを実行し、結果を文字列リストに入れるための優れた関数を作成しました。

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

レコードセットを新しい「バリアント」構造に保存して、車輪の再発明を試みないでください。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']);

多くの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 に答える