-
Добрый день всем. Сделал запрос в асинхроне...все работает. Успевай только менять процедуру обработчика до 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 в асинхроне - подскажите что может быть.
-
> Причем тот же запрос в студии возвращает результат попробуй в этом http://my-files.ru/bbqrnd , полностью на D7 - ADO сделано, если будет та же проблема тогда х.з., а если нет то можно "побороться". там по правой клавише мыши на поле запросов будет меню где есть "параметры" там выключатель асинхронного режима, его нужно включить, и переконектиться, там же в выпадающем меню.
-
Вопрос не в том, что этот запрос так, а этот запрос вот эдак. Неужели никто не работает в асинхроне с ADO... Наверняка есть какая-то ... которую нужно соблюсть.
-
> Вопрос не в том, что этот запрос так ответ не в том чтобы "какие кнопки нажать чтобы все ок" , а в том чтобы разобраться, проверить твой это косяк, или есть какая-то особенность (фича не описанная в справке) в ADO с асинхроном... я вот сколько работаю такого не заметил.
-
В вашей программе и при асинхроне и при синхроне запрос исполняется. Получается, что мой косяк. Но что может быть? У 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 - чисто дисэйблить/энейблить остальное управление.
-
> 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 Sleep(25);
Application.ProcessMessages;
end;
и еще у меня CacheSize = 25 устанавливается, не помню зачем, но возможно нужно (минимальная порция при фетче вроде). > Open; не сработает при присоединении к гриду/другим дб компонентам (Operation not allowed on a unidirectional dataset), не понимают они такого. придется "ловить" готовый в OnFetchComplete например (/ждать как у меня) и только после подключать его к гриду.
-
Спасибо за пояснения... Как-то никогда не обращал внимания на TADODataSet/TADOCommand - посмотрю. А вот насчет Вашей реализации асинхронности... Моей программе с одной задачей (выполнить запрос, выгрузить полученное в эксель) - сей монстр Application.ProcessMessages не сможет натворить делов. В более сложных с мдичайлдами... это неприемлимо. Устанешь контролировать что можно, а что нельзя во время исполнения запроса. А хотелось попробовать внутренние ресурсы использовать. Понять бы механизм реализации - вопросов бы не было.
-
предыдущий пост - мой.
-
> А вот насчет Вашей реализации асинхронности... > ... > сей монстр Application.ProcessMessages не сможет натворить делов. не настаиваю, и даже не считаю что "мой" метод правильный... просто так удобнее, в той реализации. вместо дополнительных методов/компонент 4 строчки кода, + ничего не меняется при "синхронном" вызове, условие просто не сработает т.к. на выходе из Execute статус уже будет 1, а 0 нужен для прерывателя (по ctrl+z коннект/выполнение закрывается).
> выгрузить полученное в эксель для этого сначала данные нужно получить, также как в синхронном случае, загрузка "полуфабриката" (который у тебя будет сразу после Open, без либо "моего" либо из события способе, без разницы) не сработает (хотя ты можешь и "неявно" его вытянуть, если вдруг переформировываешь данные и делаешь проход по полученному рекордсету). а получение кстати, у асинхронного метода гораздо дольше чем синхронного, можешь замерить, в той же проге из [1]. то что в студии кажется быстрее, это обман, тебе показывают первую порцию и пока ты чемто занят, в фоне подтягивают остальное.
-
Вашей программой оценивать время не совсем корректно. Да и я преследую в асинхроне только одну цель - возможность прерывания запроса в любой момент. К большому для себя сожалению обнаружил невозможность частичного/порционного получения рекордсета. Если студия способна получать кусками - значит эта невозможность "сидит" в ADO. Короче, расстроило меня это самое ADO. Спасибо за участие в проблеме. Сам еще раз попытался "пошаманить" свойствами компонент - нуль. Попробую еше ADOCommand - но есть уверенность в аналогичном поведении.
-
> Вашей программой оценивать время не совсем корректно. с чего это? точное время выполнения и получения всех данных... хочется самообмана считая время сразу после open стремящееся к 0, ну считай.
> возможность прерывания запроса в любой момент. > значит эта невозможность "сидит" в ADO. ??? Ctrl+Z у меня не работает?
> Попробую еше ADOCommand - но есть уверенность в аналогичном поведении. так и есть, аналогично, но вовсе не так как ты себе это похоже представляешь.
-
<OFFTOP> Парадокс, но факт. На Королевстве до сих пор никто не откликнулся на вопрос уважаемого Василия. <.OFFTOP>
-
> Германн © (03.04.16 02:43) [11] > > Удалено модератором
<OFFTOP> Виноват. Приношу извинения. Кто же знал, что на Королевстве проблемы с ответами. </OFFTOP>
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
|