Конференция "Базы" » recordset to stream...
 
  • guest (30.05.14 04:00) [0]

    procedure AddRecordsetToStream(stream: TStream; Recordset: _Recordset);
    var
    rs:variant;
    begin
     if(Recordset = nil) then Exit;

       rs:=Recordset as IDispatch;
       rs.Save(TStreamAdapter.Create(stream) as IUnknown, adPersistADTG);

    end;



    Данный код сохраняет рекордсет в стрим. На небольших данных всё работает отлично, но на больших (десятки и сотни тысяч записей) скорость сильно падает. Не подскажете, нет ли путей ускорения данного преобразования?

    Спасибо
  • sniknik © (30.05.14 08:05) [1]
    > скорость сильно падает.
    насколько сильно? оно и должно падать, данных больше, но как из этих слов понять адекватно ли падение возросшему количеству?

    +
    как мерял? где точки замера ставил? может основной тормоз тормозит вовсе не этот код.

    по вопросу, у датасета рекордсет которого перегоняеш в стрим DisableControls делал? так на всякий случай, скорее всего не поможет.

    ну попробуй вот так, "напрямую", сравни, мало ли...
    var
     adoStream: OleVariant;
    begin
       adoStream:= CreateOLEObject('ADODB.Stream');
       try
         Variant(DataSet.Recordset).Save(adoStream, adPersistADTG);
       finally
         adoStream:= UnAssigned;
       end;

  • guest (30.05.14 14:31) [2]

    > sniknik ©   (30.05.14 08:05) [1]

    читал ваши же посты на эту тему на этом форуме,
    сделал так:

    procedure AddRecordsetToStream3(stream: TStream; const Recordset: _Recordset);
    var
    rs: Variant;
    begin
    if(Recordset = nil) then Exit;
    try
      rs:=CreateOleObject('ADODB.Recordset');
      rs:=Recordset;
      rs.Save(TStreamAdapter.Create(stream) as IUnknown, adPersistADTG);
    finally
    end;
    end;



    суть не изменилась

    40.000 записей общим размером в 14Мб сохраняются в поток ~20 секунд!!
  • sniknik © (30.05.14 14:33) [3]
    > суть не изменилась
    код не изменился... кроме добавления 1 глупой, ни на что не влияющей строчки.
  • guest (30.05.14 14:35) [4]
    а где-то предложенный вами вот этот более безопасный вариант не смог проверить, т.к. получаю "Invalid pointer operation":


    procedure AddRecordsetToStream2(stream: TStream; Recordset: _Recordset);
    var
    st:TStreamAdapter;
    rs:variant;
    begin
     if(Recordset = nil) then Exit;
     st:=TStreamAdapter.Create(stream);
     try
       rs:=Recordset as IDispatch;
       rs.Save(st as IUnknown, adPersistADTG);
     finally
      st.Free;
     end;


    end;
  • guest (30.05.14 14:36) [5]

    > код не изменился... кроме добавления 1 глупой, ни на что
    > не влияющей строчки.


    сорри, запутался...  сейчас ваш вариант проверим..
  • guest (30.05.14 14:48) [6]
    да ваш вариант выполняется быстро

    var
    adoStream: OleVariant;
    begin
      adoStream:= CreateOLEObject('ADODB.Stream');
      try
        Variant(DataSet.Recordset).Save(adoStream, adPersistADTG);
      finally
        adoStream:= UnAssigned;
      end;



    вопрос - как adoStream перегнать в мой TStream?
  • guest (30.05.14 14:54) [7]
    нашел ваше решение в другой ветке.. вопрос снят, спасибо!)


    procedure SendDataset(Content: TStream; DataSet: TADODataSet);
    var
    adoStream: OleVariant;
    Buffer: Variant;
    PBuffer: pointer;
    size: integer;
    begin
    adoStream:= CreateOLEObject('ADODB.Stream');
    try
      Variant(DataSet.Recordset).Save(adoStream, adPersistADTG);
      size:= adoStream.Size;

      Buffer := adoStream.Read(size);
      PBuffer:= VarArrayLock(Buffer);
      try
        Content.WriteBuffer(PBuffer^, size);
      finally
        VarArrayUnlock(Buffer);
      end;
    finally
      adoStream:= UnAssigned;
    end;
    end;

  • guest (30.05.14 15:03) [8]
    не снят))

    Variant(DataSet.Recordset).Save(adoStream, adPersistADTG);

    возвращает AV

    в моем случае это

    Variant(FADOStoredProc.Recordset).Save(adoStream, adPersistADTG);
  • guest (30.05.14 15:07) [9]
    странно, тот же код только что работал.... куда копать?
  • sniknik © (30.05.14 15:34) [10]
    > возвращает AV
    обращение к не созданному/освобожденному объекту. у тебя отладчика что нет совсем? трассировкой принципиально не занимаешься?
  • guest (30.05.14 15:48) [11]

    > sniknik ©   (30.05.14 15:34) [10]


    сорри-сорри, Recordset бывает Nil, проверка на это раньше была, теперь всё ок..) спасибо еще раз)
 
Конференция "Базы" » recordset to stream...
Есть новые Нет новых   [134427   +34][b:0][p:0.002]