Como alcançar tadodataset clonado independente?
-
25-09-2019 - |
Pergunta
Os cenários são assim:
Temos uma tabela SQL. Estamos realizando uma consulta SQL nesta tabela e temos resultados em objeto 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;
Portanto, depois de clonar o conjunto de dados, meu QryClone deve possuir dados independentes (pelo menos eu pensei). No entanto, a execução de exclusão sobre Qryororyginal causa a mesma operação no QryClone. Eu não quero isso.
Alguma ideia?
Sei que poderia armazenar os dados em outros lugares, no TclientDataSet, talvez, mas gostaria de experimentar a solução acima primeiro.
Agradeço antecipadamente pelo seu tempo.
Solução
A clonagem apenas clara o cursor no conjunto de dados, sem duplicar os dados mantidos no conjunto de dados.
Se você precisar ter dois dados independentes, precisará copiar os dados do conjunto de dados original para o segundo.
Se você deseja ler ou modificar um único conjunto de dados sem alterar o cursor atual no conjunto de dados, poderá usar o método clone.
Outras dicas
Você pode usar o conjunto de registros de um tadodataSet para clonar um tadodataset.
ds1.Recordset := CloneRecordset(ds2.Recordset);
Esta versão funciona a partir de Delphi Xe. Adoint é atualizado com as definições de biblioteca de tipos para o 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;
Esta versão deve ser usada para versões do Delphi antes do Delphi XE. ADOR_TLB é gerado a partir de 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;
Eu gosto mais de realização com o TclientDataSet, porque podemos editá -lo livremente como precisamos depois de copiar.
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;
...