Comment obtenir TADODataSet cloné indépendant?
-
25-09-2019 - |
Question
Les scénarios est comme ceci:
Nous avons une table SQL. Nous effectuons une requête SQL sur cette table et nous avons des résultats dans l'objet TADOQuery.
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;
Ainsi, après le clonage du DataSet mon qryClone devrait tenir et des données indépendantes (je pensais du moins). Cependant, l'exécution sur Supprimer qryOryginal provoque la même opération sur le qryClone. Je ne veux pas que.
Toutes les idées?
Je sais que je pouvais stocker les données ailleurs, dans TClientDataSet peut-être mais je voudrais essayer d'abord la solution ci-dessus.
Merci d'avance pour votre temps.
La solution
Le clonage clone simplement le curseur sur jeu de données, ne pas dupliquer les données conservées dans l'ensemble de données.
Si vous avez besoin d'avoir deux données indépendantes, vous devez copier les données de l'ensemble de données d'origine à la seconde.
Si vous voulez lire ou modifier un seul jeu de données sans changer le curseur sur l'ensemble de données, vous pouvez utiliser la méthode Clone.
Autres conseils
Vous pouvez utiliser le recordset d'un TADODataSet à cloner un TADODataSet.
ds1.Recordset := CloneRecordset(ds2.Recordset);
Cette version fonctionne de Delphi XE. ADOInt est mis à jour avec les définitions de la bibliothèque de type pour 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;
Cette version doit être utilisée pour les versions de Delphi avant Delphi XE. ADOR_TLB est généré à partir msado28.tlb.
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;
Je ressemble plus à la réalisation avec TClientDataSet, parce que nous pouvons modifier à souhait que nous avons besoin après la copie.
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;
...