2013-03-22 2 views
1

우리는 데이터베이스를 쿼리 할 때 varchar로 한 개의 열만 있으면됩니다.데이터베이스 결과에 대한 가변 구조

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

은 내가 지금 찾고 있어요 것은 기본적으로 동일한 기능이지만, 당신이 '돈 여러 열 결과 : 그래서 나는 데이터베이스를 조회하고 stringlist에 결과를 넣어위한 좋은 기능을했습니다 데이터 유형이 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

TClientDataSet과 같이 연결이 끊긴 메모리 내 TDataSet 하위 항목을 사용해야합니다.

새로운 "변형"구조로 레코드 세트를 저장하여 휠을 다시 발명하려고 시도하지 마십시오. TClientDataSet에는 "임시"데이터 구조를 조작하는 데 필요한 모든 기능이 이미 포함되어 있습니다. LockType=ltBatchOptimistic와 예 A TADODataSet를 들어,

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에 따라 인 - 메모리 (클라이언트) 데이터 세트로 사용 할 수있는 능력을 가지고 : 여기

당신이 TClientDataSet 구조를 생성하는 방법이다 서버에서 결과 세트를 가져온 다음 연결이 끊긴 상태로 유지 될 수 있습니다.

+0

나는 이것이 내가 조사 할 필요가있는 것이라고 생각한다. –

1

오픈 데이터 세트로 작업하는 것이 어떻습니까? 그들은 대개 서버를 차단하지 않습니다. 데이터 세트에서 원하는 데이터로 데이터를 복사하는 것은 필요하지 않은 추가 오버 헤드입니다.

데이터 세트는 원하는 기능을 정확하게 제공합니다. 가변 행과 행이있는 행렬.

EDIT : 그러나 자주 데이터 집합을 반복하는 경우 관련 정보가 들어있는 클래스를 만든 다음 빠른 목록 구조로 필요한 일반 목록, 사전, 트리 또는 기타로 데이터를 복사해야합니다.

물론 데이터 세트만큼 융통성있는 스마트 한 건물을 생각할 수도 있지만 더 일반적인 일은 성능이 떨어집니다 (일반적으로).

+0

몇 가지 문제가 있습니다. 1 : 성능이 중첩 된 쿼리에 실제로 영향을 미치고 사용하는 함수가 데이터베이스를 사용한다는 것이 항상 명확하지 않기 때문에 중첩이 항상 명확하지는 않습니다. 2 : 열린 데이터 세트를 작업 할 때 데이터를 열었을 때 데이터가 중간인지 여부를 예측하기 란 쉽지 않습니다. –

+0

일단 데이터 세트를 열면 정적입니다. 물건을 다른 구조체에 복사하거나 반복하는 데 차이가 없습니다. 그러나 실적이 문제가되는 경우 (즉, 자주 검색해야하는 경우) 데이터를 다른 구조로 복사해야합니다. POCO 클래스와 사전을 추천합니다. – alzaimar

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

+0

@bummi 우리는 일부 oleautomation을 사용하며이 접근법이 실제로 적합하다고 생각합니다. –

관련 문제