Конференция "Базы" » Редактируемый набор данных через TADOCommand [MSSQL]
 
  • DmitriyG. © (25.04.12 08:57) [0]
    Необходимо в результате выполнения запроса через объект
    TADOCommand в TADOQuery получать редактируемый набор данных.
    Вот упрощенная процедура....


    procedure OpenRecordset(const connMain : TADOConnection; Query : TADOQuery; const Request : string);
    var
     cmd: TADOCommand;
     rst: _Recordset;
    begin
     cmd := TADOCommand.Create(nil);
     try
       cmd.Connection := connMain;
       cmd.CommandText := Request;
       rst := cmd.Execute;
       //Получаем данные
       if  not ((rst.State = adStateClosed)) then
         Query.Recordset := rst;
     finally
       cmd.Free;
     end;
    end;


    После выполнения:
       queryMain.LockType = ltReadOnly
    Как сделать чтобы LockType было равно ltOptimistic?

    Пробовал так:
    queryMain.Recordset := rst.Clone(adLockOptimistic);
    Вылетает AV: EOleException: "Arguments are of the wrong type,
    are out of acceptable range, or ane in conflict with one another"





  • AV © (25.04.12 09:37) [1]
    ИМХО так
    набор данных присвоен, а кто он и откуда - неизвестно, поэтому и нельзя редактировать, т.к. неизвестно куда его запостить потом

    Если так
    try
      cmd.Connection := ac1;
      cmd.CommandText := 'SELECT * FROM [DialerDetail].[dbo].[AAA]';
      rst := cmd.Execute;
      aq1.Recordset := rst;
      aq1.SQL.Text := 'SELECT * FROM [DialerDetail].[dbo].[AAA]';
      aq1.Active := True;
    то редактируется.

    Тут вроде бы просто исполняется обычный квери, но если посмотрим внутрь

    procedure TCustomADODataSet.OpenCursor(InfoQuery: Boolean);

     if not Assigned(Recordset) then
     begin
       InitializeConnection;
       InitializeRecordset;
       Recordset.Open(Source, ActiveConnection,
         CursorTypeValues[FCursorType], LockTypeValues[FLockType],
         Integer(CommandTypeValues[CommandType]) + ExecuteOptionsToOrd(ExecuteOptions));
       while Recordset.State = adStateClosed do
       try
         FRecordsetObject := Recordset.NextRecordset(VarRecsAffected);
         if Recordset = nil then Abort;
       except
         DatabaseError(SNoResultSet, Self);
       end;
     end else
       EnableEvents;

    т.е. не полностью запрос идет.

    Пусть поправят, если не так понимаю.
  • DmitriyG. © (26.04.12 08:48) [2]
    Хм... Действительно... Становится редактируемым...
    Спасибо БОЛЬШОЕ!!!

    Посмотрел в профайлере (MSSQL) операция действительно не порождает второй запрос, но порождает:
    sp_opencursor
    sp_fetch
    sp_fetch
    .....
    .......
    sp_fetch
    sp_fetch

    Работает немного дольше, но вроде бы не сильно принципиально... Надо еще конечно потестировать...

    Еще раз спасибо...

    ЗЫ Интересно все таки, а без таких хитростей, напрямую через ADOCommand сделать запрос редактируемым можно? Должна же быть более явная опция..
  • AV © (26.04.12 09:51) [3]
    Не за что :), просто предположил/попробовал

    > Посмотрел в профайлере (MSSQL) операция действительно не
    > порождает второй запрос, но порождает:
    > sp_opencursor
    > sp_fetch
    > sp_fetch
    > .....
    > .......
    > sp_fetch
    > sp_fetch

    надо еще посмотреть, что делается в TCustomADODataSet, покликать ctrl+Lclick на процедурках внутренних его
    Может еще что нарыть получится, что бы fetch не было.
  • sniknik © (26.04.12 09:56) [4]
    явное это TADOCommand для команд, TADODataSet для возврата/обработки данных. все остальное извращения... и как делается можно в коде тех же извращающих суть ADO компонент - TADOQuery, TADOStoredProc посмотреть.

    кстати твоя "обертка" не обработает даже простейшего пакета, с ну типа -
    INSERT INTO table ... ;
    SELECT * FROM table ;
    что довольно часто используется, для обновления пары таблиц например (вторую с авто инкрементом от первой) и одновременным возвратом результата. и да, для "буквоедов", это можно обойти, используя дополнительную пару команд. но зачем? сначала вставлять себе же палку в колеса, а после придумывать как бы сделать чтобы оно ехать не мешала...
    хрень делаешь в общем.
  • DmitriyG. © (26.04.12 19:16) [5]

    > надо еще посмотреть, что делается в TCustomADODataSet, покликать
    > ctrl+Lclick на процедурках внутренних его
    > Может еще что нарыть получится, что бы fetch не было.
    >
    >


    Надо... Постараюсь глянуть....

    > sniknik ©   (26.04.12 09:56) [4]
    > явное это TADOCommand для команд, TADODataSet для возврата/обработки
    > данных. все остальное извращения... и как делается можно
    > в коде тех же извращающих суть ADO компонент - TADOQuery,
    >  TADOStoredProc посмотреть.
    >


    Т.е. советуете не использовать ни TADOCommand ни TADOQuery? А запрос делать напрямую через TADODataSet? То же вариант... Если получится напишу...
    Просто сделал асинхронный запрос (с возможностью отмены и остановки Fetch) через TADOCommand, а потом появилась необходимо напрямую редактировать полученные данные - вот и стал искать всякие извращения...
  • sniknik © (26.04.12 19:23) [6]
    > Т.е. советуете не использовать ни TADOCommand ни TADOQuery?
    где? где видишь совет не использовать?

    p.s. уже боюсь что либо говорить, все извращают...
  • Anatoly Podgoretsky © (26.04.12 19:41) [7]
    > DmitriyG.  (26.04.2012 19:16:05)  [5]

    Ну как так можно читать.
  • DmitriyG. © (27.04.12 12:24) [8]
    Эх... Ну заработался...
 
Конференция "Базы" » Редактируемый набор данных через TADOCommand [MSSQL]
Есть новые Нет новых   [134431   +9][b:0][p:0.001]