Конференция "Базы" » ADO в асинхроне [D7, MSSQL]
 
  • Вас (29.03.16 18:44) [0]
    Добрый день всем.
    Сделал запрос в асинхроне...все работает. Успевай только менять процедуру обработчика до Open, но...
    Запрос типа select TOP 10000 * FROM People - отрабатывает без проблем. Останавливается по кнопке в любой момент хоть в процессе "прогресса" до "комплита", хоть в момент когда вызван обработчик "комплита" (там есть соотвествующий кусок). После останова и перезапуска - без проблем получаю результат.
    А запрос...

    DECLARE @Mnn varchar(max) =
    'Вася Пупкин
    Сеня Иванов
    '

    DECLARE @table table (PeopleName varchar(950), PeopleID int)
    INSERT INTO @table(PeopleName)
    SELECT strval,Num FROM dbo.parse_str(@Mnn, char(13)+char(10))

    UPDATE @table
    SET PeopleID = isnull(pe.PeopleID,0)
    FROM @table t
    LEFT JOIN dbo.People pe ON pe.PeopleName = t.PeopleName

    SELECT * FROM @table

    Напрочь не хочет отрабатывать. Не вызывается обработчик "прогресса" и даже обработчик "комплита".
    Можно (по кнопке) закрыть запрос, закрыть программу...но результата не дождаться. Причем тот же запрос в студии возвращает результат (коннект под той же учеткой, что и в программе).
    После этого запроса даже запрос select TOP 10000 * FROM People с тем же эффектом...т.е. результат не дождаться, только перезапуск программы.
    Сначала подумал, что при асинхроне некий поток вызывает обработчики без Synhronize - убрал все VCL-ки... SET NOCOUNT ON вставил... безрезультатно.
    Может у кого-то есть успешный опыт работы ADO, MS SQL, Д7 в асинхроне - подскажите что может быть.
  • sniknik © (30.03.16 10:54) [1]
    > Причем тот же запрос в студии возвращает результат
    попробуй в этом http://my-files.ru/bbqrnd , полностью на D7 - ADO сделано, если будет та же проблема тогда х.з., а если нет то можно "побороться".

    там по правой клавише мыши на поле запросов будет меню где есть "параметры" там выключатель асинхронного режима, его нужно включить, и переконектиться, там же в выпадающем меню.
  • vpivo © (31.03.16 06:02) [2]
    Вопрос не в том, что этот запрос так, а этот запрос вот эдак. Неужели никто не работает в асинхроне с ADO... Наверняка есть какая-то ... которую нужно соблюсть.
  • sniknik © (31.03.16 08:49) [3]
    > Вопрос не в том, что этот запрос так
    ответ не в том чтобы "какие кнопки нажать чтобы все ок" , а в том чтобы разобраться, проверить твой это косяк, или есть какая-то особенность (фича не описанная в справке) в ADO с асинхроном... я вот сколько работаю такого не заметил.
  • vpivo © (01.04.16 07:22) [4]
    В вашей программе и при асинхроне и при синхроне запрос исполняется. Получается, что мой косяк. Но что может быть? У ADOConnection выставлено ConnectOptions = coAsyncConnect, LoginPrompt = False, остальное - по умолчанию. У ADOQuery в ExecuteOptions выставлены eoAsyncExecute и eoAsyncFetch. Определены два эвента OnFetchComplete и OnFetchProgress. Причем изначально не было ADOConnection - просто прописывалась строка подключения, но выскочила ошибка типа "для асинхронного исполнения требуется асинхронное подключение" - добавил ADOConnection и связал с ним ADOQuery. Кода-то всего ничего...
    with quMain do begin
      SQL.Text := meQuery.Text;
      OnFetchComplete := quMainComplete;
      btReady.Caption := 'Прекратить';
      Open;
    end;
    Единственно, еще определены обработчики quMain.BeforeOpen и quMain.AfterClose - чисто дисэйблить/энейблить остальное управление.
  • sniknik © (01.04.16 14:49) [5]
    > ConnectOptions = coAsyncConnect
    это бессмысленно, действие на раз, момент коннекта с сервером. если конечно не переключать дефолтное KeepConnection (смысл только для долгих подключений через инет) и не усложнить себе жизнь.
    у меня coConnectUnspecified в общем. + CursorLocation = clUseServer (для датасета тоже нужно, если его использовать, насколько помню, в данной проге у меня этого нет, т.к. исполняются запросы в ADOCommand)

    > У ADOQuery
    никогда не использовал, и никому не советую... только TADODataSet/TADOCommand

    > eoAsyncExecute и eoAsyncFetch
    также.

    > OnFetchComplete и OnFetchProgress.
    у меня немного не так, но и это должно работать/раньше пробовал. у меня из-за особенностей (сдваивания метода синхронного/асинхронного и и желания общей обработки) сделано проверкой статуса:
           Recordset:= CmdWork.Execute(RecordsAffected, EmptyParam);

           while (Recordset.State > 1) do begin //stClosed=0, stOpen=1 //сработает только при асинхронном режиме у CmdWork...
             Sleep(25);
             Application.ProcessMessages;
           end;

     

    и еще у меня CacheSize = 25  устанавливается, не помню зачем, но возможно нужно (минимальная порция при фетче вроде).

    > Open;
    не сработает при присоединении к гриду/другим дб компонентам (Operation not allowed on a unidirectional dataset), не понимают они такого. придется "ловить" готовый в OnFetchComplete например (/ждать как у меня) и только после подключать его к гриду.
  • Вас (01.04.16 15:13) [6]
    Спасибо за пояснения... Как-то никогда не обращал внимания на TADODataSet/TADOCommand - посмотрю. А вот насчет Вашей реализации асинхронности... Моей программе с одной задачей (выполнить запрос, выгрузить полученное в эксель) - сей монстр  Application.ProcessMessages не сможет натворить делов. В более сложных с мдичайлдами... это неприемлимо. Устанешь контролировать что можно, а что нельзя во время исполнения запроса. А хотелось попробовать внутренние ресурсы использовать. Понять бы механизм реализации - вопросов бы не было.
  • vpivo © (01.04.16 15:14) [7]
    предыдущий пост - мой.
  • sniknik © (01.04.16 16:37) [8]
    > А вот насчет Вашей реализации асинхронности...
    > ...
    > сей монстр  Application.ProcessMessages не сможет натворить делов.
    не настаиваю, и даже не считаю что "мой" метод правильный... просто так удобнее, в той реализации. вместо дополнительных методов/компонент 4 строчки кода, + ничего не меняется при "синхронном" вызове, условие просто не сработает т.к. на выходе из Execute статус уже будет 1, а 0 нужен для прерывателя (по ctrl+z коннект/выполнение закрывается).

    > выгрузить полученное в эксель
    для этого сначала данные нужно получить, также как в синхронном случае, загрузка "полуфабриката" (который у тебя будет сразу после Open, без либо "моего" либо из события способе, без разницы) не сработает (хотя ты можешь и "неявно" его вытянуть, если вдруг переформировываешь данные и делаешь проход по полученному рекордсету).
    а получение кстати, у асинхронного метода гораздо дольше чем синхронного, можешь замерить, в той же проге из [1]. то что в студии кажется быстрее, это обман, тебе показывают первую порцию и пока ты чемто занят, в фоне подтягивают остальное.
  • vpivo © (02.04.16 11:15) [9]
    Вашей программой оценивать время не совсем корректно. Да и я преследую в асинхроне только одну цель - возможность прерывания запроса в любой момент. К большому для себя сожалению обнаружил невозможность частичного/порционного получения рекордсета. Если студия способна получать кусками - значит эта невозможность "сидит" в ADO. Короче, расстроило меня это самое ADO. Спасибо за участие в проблеме. Сам еще раз попытался "пошаманить" свойствами компонент - нуль. Попробую еше ADOCommand - но есть уверенность в аналогичном поведении.
  • sniknik © (02.04.16 16:49) [10]
    > Вашей программой оценивать время не совсем корректно.
    с чего это? точное время выполнения и получения всех данных... хочется самообмана считая время сразу после open стремящееся к 0, ну считай.

    > возможность прерывания запроса в любой момент.
    > значит эта невозможность "сидит" в ADO.
    ???
    Ctrl+Z у меня не работает?

    > Попробую еше ADOCommand - но есть уверенность в аналогичном поведении.
    так и есть, аналогично, но вовсе не так как ты себе это похоже представляешь.
  • Германн © (03.04.16 02:43) [11]
    <OFFTOP>
    Парадокс, но факт. На Королевстве до сих пор никто не откликнулся на вопрос уважаемого Василия.
    <.OFFTOP>
  • Германн © (06.04.16 01:22) [12]

    > Германн ©   (03.04.16 02:43) [11]
    >
    > Удалено модератором

    <OFFTOP>
    Виноват. Приношу извинения.
    Кто же знал, что на Королевстве проблемы с ответами.
    </OFFTOP>
  • имя (21.04.16 13:36) [13]
    Удалено модератором
  • имя (21.04.16 14:08) [14]
    Удалено модератором
  • имя (21.04.16 14:37) [15]
    Удалено модератором
 
Конференция "Базы" » ADO в асинхроне [D7, MSSQL]
Есть новые Нет новых   [134427   +34][b:0][p:0.001]