2013-03-22 63 views
1

很多時候,當我們查詢數據庫,我們只需要使用VARCHAR一列。 所以我做了一個很好的功能,查詢數據庫,並把結果放在一個StringList的:數據庫變結構導致

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; 

我覺得這是值得的基礎上。

回答

7

您應該使用任何斷開內存TDataSet後裔,如TClientDataSet

不要試圖通過存儲來重新發明輪子一個記錄集的一些新的「變體」結構。 A 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的內存(客戶端)數據集的能力,例如TADODataSetLockType=ltBatchOptimistic可以從服務器獲取結果集,然後保持斷開連接。

+0

我認爲這是我需要研究的內容。 – 2013-03-22 15:18:15

1

你爲什麼不喜歡用開放的數據集進行操作?他們通常不會阻止服務器。將數據集中的數據複製到任何你想要的是額外的開銷,這很可能不是必需的。

的數據集提供正是你想要的功能:具有可變的行和列的矩陣。

編輯:但是,如果你經常迭代數據集,你應該考慮創建一個持有相關信息的類,然後將數據複製到通用列表,字典,樹或任何你需要的快速查找結構。

當然,你能想到的東西構建智能,可以是作爲一個數據集,但靈活的:較爲一般的東西搞定,性能越差(一般)。

+0

我們遇到了一些問題,主要是2:1:性能真的嵌套查詢遭受因爲它並不總是很清楚的是,你使用的功能使用的數據庫,所以嵌套並不總是很清楚。 2:在開放數據集上工作時,很難預測數據在打開時是否相同,以及在何時完成數據。 – 2013-03-22 15:17:16

+0

一旦你打開數據集,它就是靜態的。將這些東西複製到另一個結構或迭代它們沒有區別。然而,如果性能是一個問題,即你必須經常搜索,你當然必須將數據複製到另一個結構中:我會推薦POCO類和字典或類似的。 – alzaimar 2013-03-22 15:47:37

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; 
+0

那些變體數組非常重量級。如果可以的話,我寧願簡單地使用'Variant'數組,但如果它適合Excel數據交換...儘管我認爲最好的可能是由@kobik建議的'TCustomDataSet'。 [+1] – TLama 2013-03-22 14:32:41

+0

@bummi我們使用了一些oleautomation,我認爲這種方法非常適合它。 – 2013-03-22 15:19:16