如何实现独立克隆的TADODataSet?

时间:2010-02-04 09:52:08

标签: delphi cloning tadoquery tadodataset

场景如下:

我们有一些SQL表。我们正在对此表执行SQL查询,并且我们在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;

因此,在克隆DataSet之后,我的qryClone应该保存并且独立数据(至少我是这么认为的)。但是,在qryOryginal上执行Delete会导致qryClone上的操作相同。我不希望这样。

有什么想法吗?

我知道我可以将数据存储在TClientDataSet中的其他位置,但我想首先尝试上述解决方案。

提前感谢您的时间。

4 个答案:

答案 0 :(得分:8)

您可以使用TADODataSet的记录集来克隆TADODataSet。

ds1.Recordset := CloneRecordset(ds2.Recordset);

此版本适用于Delphi XE。 ADOInt使用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;

此版本必须用于Delphi XE之前的Delphi版本。 ADOR_TLB由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;

答案 1 :(得分:0)

克隆只是将光标克隆在数据集上,而不是复制数据集中保存的数据。

如果您需要两个独立的数据,则必须将原始数据集中的数据复制到第二个数据。

如果要在不更改数据集上的当前光标的情况下读取或修改单个数据集,则可以使用克隆方法。

答案 2 :(得分:0)

我更喜欢用TClientDataSet实现,因为我们可以在复制后自由编辑它。

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;

    ...

答案 3 :(得分:0)

第二种方式,使用Devexpress dxMemData。非常有用且易于使用的组件。

var
  MD: TdxMemData;
  SP: TADOStoredProc;
...
...
  // and after opening stored procedure:
  MD.Close;
  MD.Open;
  MD.LoadFromDataset(SP);