Wie unabhängig geklonten TADODataSet zu erreichen?
-
25-09-2019 - |
Frage
Die Szenarien ist wie folgt aus:
einige SQL-Tabelle haben. Wir sind eine SQL-Abfrage auf diese Tabelle durchführen und wir haben Ergebnisse in TADOQuery Objekt.
var
qryOryginal, qryClone: TADOQuery;
begin
//setup all the things here
qryOryginal.Active := True;
qryClone.Clone(qryOryginal, ltBatchOptimistic);
qryOryginal.Delete; //delete in qryOryginal casues that qryClone deletes its record too!
end;
So, nachdem das DataSet meine qryClone klonen sollte und unabhängige Daten halten (zumindest dachte ich, so). Doch auf qryOryginal Löschen Ausführen bewirkt, dass die gleiche Operation auf dem qryClone. Ich will das nicht.
Irgendwelche Ideen?
Ich weiß, dass ich die Daten an anderer Stelle speichern könnte, in TClientDataSet vielleicht, aber ich möchte zunächst die obige Lösung versuchen.
Vielen Dank im Voraus für Ihre Zeit.
Lösung
Das Klonen klont nur die Cursor auf Dataset, die Daten nicht gehalten in dem Datensatz zu duplizieren.
Wenn Sie zwei voneinander unabhängige Daten haben müssen, dann müssen Sie die Daten aus dem ursprünglichen Datensatz auf den zweiten kopieren.
Wenn Sie einen einzelnen Datensatz lesen oder ändern wollen, ohne auf dem Datensatz die aktuellen Cursor zu ändern, dann können Sie Clone-Methode verwenden.
Andere Tipps
Sie können den Re-Cord eines TADODataSet verwenden, um einen TADODataSet zu klonen.
ds1.Recordset := CloneRecordset(ds2.Recordset);
Diese Version funktioniert von Delphi XE. ADOInt mit der Typbibliothek Definitionen aktualisiert MDAC 2.8
uses ADOInt, Variants;
function CloneRecordset(const Data: _Recordset): _Recordset;
implementation
function CloneRecordset(const Data: _Recordset): _Recordset;
var
newRec: _Recordset;
stm: Stream;
begin
newRec := CoRecordset.Create as _Recordset;
stm := CoStream.Create;
Data.Save(stm, adPersistADTG);
newRec.Open(stm, EmptyParam, CursorTypeEnum(adOpenUnspecified),
LockTypeEnum(adLockUnspecified), 0);
Result := newRec;
end;
Diese Version muss für Versionen von Delphi vor Delphi XE verwendet werden. ADOR_TLB aus msado28.tlb erzeugt wird.
uses ADOInt, ADOR_TLB, Variants;
function CloneRecordset(const Data: ADOInt._Recordset): ADOInt._Recordset;
implementation
function CloneRecordset(const Data: ADOInt._Recordset): ADOInt._Recordset;
var
newRec: ADOR_TLB._Recordset;
stm: Stream;
begin
newRec := ADOR_TLB.CoRecordset.Create as ADOR_TLB._Recordset;
stm := CoStream.Create;
(Data as ADOR_TLB._Recordset).Save(stm, adPersistADTG);
newRec.Open(stm, EmptyParam, CursorTypeEnum(adOpenUnspecified),
LockTypeEnum(adLockUnspecified), 0);
Result := newRec as ADOInt._Recordset;
end;
ich mehr wie Realisierung mit TClientDataSet, weil wir es frei bearbeiten können, wie wir brauchen nach dem Kopieren.
var
MyADOStoredProc: TADOStoredProc;
DataSetProvider: TDataSetProvider;
ClientDataSet: TClientDataSet;
DataSource: TDataSource;
...
// here now we have an opened ADOStoredProc object MyADOStoredProc
// let's copy data from it
DataSetProvider := TDataSetProvider.Create(Self);
DataSetProvider.Name := 'DataSetProvider' + FormatDateTime('_yyyy_mm_dd_hh_nn_ss', Now);
DataSetProvider.DataSet := MyADOStoredProc;
ClientDataSet := TClientDataSet.Create(Self);
ClientDataSet.ProviderName := DataSetProvider.Name;
DataSource := TDataSource.Create(Self);
DataSource.DataSet := ClientDataSet;
ClientDataSet.Open;
MyADOStoredProc.Close;
ClientDataSet.First;
// here we can modify our ClientDataSet as we need, besides MyADOStoredProc is closed
if not ClientDataSet.Eof then
ClientDataSet.Delete;
...