4

场景是这样的:

我们有一些 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 执行删除会导致对 qryClone 执行相同的操作。我不想要那个。

有任何想法吗?

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

在此先感谢您的时间。

4

4 回答 4

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;
于 2011-01-25T08:56:41.620 回答
1

我更喜欢用 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;

    ...
于 2018-04-17T17:43:52.370 回答
0

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

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

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

于 2010-02-04T15:05:41.977 回答
0

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

var
  MD: TdxMemData;
  SP: TADOStoredProc;
...
...
  // and after opening stored procedure:
  MD.Close;
  MD.Open;
  MD.LoadFromDataset(SP);
于 2020-06-02T06:46:11.070 回答