|
Асинхронный запрос к серверу
|
|||
---|---|---|---|
#18+
Нужен совет знатоков, идея, ссылка. Как запустить асинхронный запрос, который не возвращает записи, а скажем запускает хранимую процедуру на серверу мне известно. Но как запустить асинхронно запрос, возвращающий некие данные, да ещё таким образом, чтобы в случае чего пользователь мог бы прервать запрос? Биллинг крутиться на ORACLE 11g. Таблицы на сервере огромные (есть и такие, где больше 100 млн. записей). Поэтому многие запросы работают очень и очень медленно (бывает и больше часа). Что я сделал? В отдельной таблице храню тексты запросов. По нажатию кнопки открывается форма, куда пользователь вводит нужные ему параметры и после нажатия кнопки, программа находит нужный SQL текст запроса из той таблицы, подставляет нужные параметры и запускает запрос к серверу. Вот тут у меня самое узкое место. Бывает, что пользователь ошибся с параметром и хочет перезапустить запрос. Но не тут то было! Никакой Break, Ctrl + Break и долгое удержание Esc не помогает. Только и только убить через task manager и звонок администратору базы Oracle, чтобы тот удалил висячую сессию. И самое ужасное пока крутиться запрос в Access'е нечего делать, только курить и плевать в потолок. Прочёл несколько топиков, где советуют использовать ADODB асинхронно. ОК. Не вопрос, ADO значит ADO. Но вот не могу врубиться, как потом результат вывести пользователю и как поджидать нужное время когда запрос будет готов? Создавать временные таблицы с тем, чтобы полученные данные хранить там - не вариант. Дело в том, что в Oracle нет временных таблиц, на самом деле все таблицы постоянные, их не создают "на лету". Да и для этого нужно быть админом в Oracle. А я всего лишь "читатель" там. :( Сейчас пытаюсь реализовать вот такую идею: 1) В MS Access создаю глобальную переменную с типом данных ADODB.Recordset 2) После нажатия кнопки программа не запускает запрос к серверу, а запускает VB скрипт, который и будет коннектиться к серверу ORACLE (правда придётся переспрашивать у пользователя логин и пароль), использует именно ту глобальную переменную рекордсет и попробует асинхронно получить данные и на этом работа VB скрипта заканчивается. 3) Таймером формы проверяю состояние рекордсета. Если набор записей готов, то как-нибудь нужно пользователю передать в виде таблицы. Тут ещё и такой момент реализовать надо. Если пользователь передумал, то как-то всё нужно прекратить. Ну уберу таймер. Рекордсет приравняю на "ничего" (Nothing). Пока не всё гладко получается. Многовато ошибок, да и работает нестабильно. Может кто столкнулся с такой проблемой и решил как-то получше? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.12.2016, 20:13 |
|
Асинхронный запрос к серверу
|
|||
---|---|---|---|
#18+
Ещё 1 вопрос. Если я открываю какую-либо линкованную таблицу, то Access спрашивает 1 раз пароль. Потом сколько бы не открывал таблицу и запросы к серверу, Access не спрашивает пароль. Стало быть где-то в кеше запоминает учётные записи. Как-нибудь можно программно вытащить эти данные? Мне нужно их использовать в ADO. Ну или как-то строку подключения как-нибудь можно наколдовать так, чтобы Access не спрашивал больше пароли, когда работаю и с ADO? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.12.2016, 20:20 |
|
Асинхронный запрос к серверу
|
|||
---|---|---|---|
#18+
Не знаю какмногие запросы работают очень и очень медленно (бывает и больше часа). Не знаю какубить через task manager и звонок администратору базы Oracle, чтобы тот удалил висячую сессию Предлагаю костыльное, но несложное в реализации, решение. На хосте с Oracle запускается внешнее приложение, которое выполняет роль "помощника". Ну или "посредника". Что оно делает: 1) Принимает от приложения Access "заявку" на выполнение запроса с текстом этого запроса и организует выполнение сервером этого запроса; 2) Принимает от приложения заявку на прерывание ранее переданного запроса и организует останов его выполнения (снятие сессии); 3) Формирует для приложения Access уведомление, что запрос выполнен и его результат доступен. Думаю, всё остальное понятно... Не знаю какКак-нибудь можно программно вытащить эти данные?А запросить в приложении этот пароль ДО того, как пользователь выполнит первое обращение к данным на сервере, сформировать на его основе строку подключения, проверить подключение (и если не установлено - запросить пароль заново) и использовать его в текущей сессии что помешало? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.12.2016, 21:21 |
|
Асинхронный запрос к серверу
|
|||
---|---|---|---|
#18+
Akina, Спасибо за ответ. AkinaПредлагаю костыльное, но несложное в реализации, решение. На хосте с Oracle запускается внешнее приложение, которое выполняет роль "помощника". Ну или "посредника". Что оно делает: 1) Принимает от приложения Access "заявку" на выполнение запроса с текстом этого запроса и организует выполнение сервером этого запроса; 2) Принимает от приложения заявку на прерывание ранее переданного запроса и организует останов его выполнения (снятие сессии); 3) Формирует для приложения Access уведомление, что запрос выполнен и его результат доступен. Никогда не сталкивался с таким приложением. Попробую посоветоваться с админами. Может у них уже есть нечто похожее. Возникла ещё и такая идея. Что если программно открою новое приложение Excel (даже если у пользователя уже открыто), создаю новый пустой файл, пишу программно текст макроса там и запускаю этот макрос. Ну а потом в Access таймером время от времени проверяю как дела с экселем. Правда как остановить макрос экселя в случае чего? Да и когда эксел занят не любит он когда его кто-то беспокоит (в смысле не отвечает на внешние запросы). Другая идея, почти похожая. Создаю программно текстовый файл с расширением ".vbs", запускаю VB скрипт, который сначала отправив запрос на сервер получает набор записей и создаёт на их основе файл ".csv". А в Access опять таки таймером проверяю не появился ли файлик ".csv", если да, то его открываю. И здесь проблема! Как остановить скрипт и самое главное, чтобы не было висячих сессий на стороне Oracle? Иначе админы когда-нибудь закроют лавочку (в смысле доступ). ))) AkinaА запросить в приложении этот пароль ДО того, как пользователь выполнит первое обращение к данным на сервере, сформировать на его основе строку подключения, проверить подключение (и если не установлено - запросить пароль заново) и использовать его в текущей сессии что помешало? Свою формочку подсунуть? Допустим так я и сделаю. Но как потом использовать логин и пароль пользователя? Пробежаться по всем таблицам и запросам к серверу и везде менять строку подключения, да ещё так, чтобы там остались следи от учётной записи? Не вариант. Могу конечно программно создать файл DSN и внутри написать. Ну и тогда любой пользователь сможет прочесть блокнотом содержимое файла DSN. С точки зрения безопасности не айс. Сейчас у всех настроен DSN. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2016, 03:54 |
|
Асинхронный запрос к серверу
|
|||
---|---|---|---|
#18+
Страдания юноговертера... А чо, Код: vbnet 1. 2. 3.
для оракала не работает? ЗЫ. Изобретатель квадратного колеса. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2016, 06:14 |
|
Асинхронный запрос к серверу
|
|||
---|---|---|---|
#18+
Не знаю как, Я бы порекомендовал смотреть в первую очередь возможности самого Оракла, там можно много чего сделать, в том числе асинхронный процессинг. Посмотрите, например, вот это и попробуйте покопать в этом направлении. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2016, 06:37 |
|
Асинхронный запрос к серверу
|
|||
---|---|---|---|
#18+
aleks2Страдания юноговертера... А чо, Код: vbnet 1. 2. 3.
для оракала не работает? ЗЫ. Изобретатель квадратного колеса. А Вы сами пробовали? Покажите весь листинг. Как только объявляете recordset вот таким образом программа не остановится, а сразу перейдёт к следующей строке. И как потом действовать дальше? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2016, 07:29 |
|
Асинхронный запрос к серверу
|
|||
---|---|---|---|
#18+
MrShinНе знаю как, Я бы порекомендовал смотреть в первую очередь возможности самого Оракла, там можно много чего сделать, в том числе асинхронный процессинг. Посмотрите, например, вот это и попробуйте покопать в этом направлении. За ссылку спасибки! Ушёл читать и изучать. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2016, 07:43 |
|
Асинхронный запрос к серверу
|
|||
---|---|---|---|
#18+
Не знаю какНикогда не сталкивался с таким приложением. Попробую посоветоваться с админами. Может у них уже есть нечто похожее. Вот уж вряд ли. Я имею в виду создание такого приложения самостоятельно - например, в формате VBS-скрипта. Плюс, возможно, задействование штатного планировщика (вроде в составе сервера Oracle отсутствует свой собственный планировщик). Не знаю какЧто если программно открою новое приложение Никакого принципиального отличия от текущего положения дел... Не знаю какСоздаю программно текстовый файл с расширением ".vbs", запускаю VB скрипт, который сначала отправив запрос на сервер получает набор записей и создаёт на их основе файл ".csv". А в Access опять таки таймером проверяю не появился ли файлик ".csv", если да, то его открываю. И здесь проблема! Как остановить скрипт и самое главное, чтобы не было висячих сессий на стороне Oracle? Да просто этот скрипт должен создаваться и выполняться на стороне сервера. Причём создаваться статически (это и будет то самое приложение). И создавать не файл CSV, а таблицу на сервере с результатами выполнения запроса и уникальным автогенерируемым именем, которое и будет возвращаться и как признак, что запрос выполнен, и как источник данных. из которого следует получать результат обработки.. Не знаю какСвою формочку подсунуть? Допустим так я и сделаю. Но как потом использовать логин и пароль пользователя? Пробежаться по всем таблицам и запросам к серверу и везде менять строку подключения, да ещё так, чтобы там остались следи от учётной записи? Не вариант. Могу конечно программно создать файл DSN и внутри написать. Ну и тогда любой пользователь сможет прочесть блокнотом содержимое файла DSN. С точки зрения безопасности не айс. Сейчас у всех настроен DSN. Всё так. Запросил пароль. Собрал строку подключения. Если хочется - создал файл DSN (нахрена только он нужен в этом случае?). Установил соединение. Если создавался файл DFSN - прибил его. И спокойно пользуешь соединение. Оборвётся ежели - реконнект. Ну а логин-пароль (а лучше готовую строку подключения) в течение сеанса можно как бы и в переменной хранить. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2016, 07:51 |
|
Асинхронный запрос к серверу
|
|||
---|---|---|---|
#18+
а если на стороне оракла повестить свой диспетчер-прибиватель сессий? Задача сведётся к "как отыскать именно мой запрос среди других исполняемых в данный момент, и кильнуть сессию этого запроса". Ну например - запускаешь выборку данных как обычно в синхронном режиме select 'мой уникальный ID запроса' as dummy, нужные поля from нужные таблицы ... , у пользователя перед мордой висит кнопка "Прервать выборку", которая отправляет 'мой уникальный ID запроса' ораклиному "диспетчеру-прибивателю", тот через анализ v$ находит твой исполняющийся select 'мой уникальный ID запроса' as dummy..., и делает ему kill session. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2016, 08:08 |
|
Асинхронный запрос к серверу
|
|||
---|---|---|---|
#18+
Не знаю какaleks2Страдания юноговертера... А чо, Код: vbnet 1. 2. 3.
для оракала не работает? ЗЫ. Изобретатель квадратного колеса. А Вы сами пробовали? Покажите весь листинг. Как только объявляете recordset вот таким образом программа не остановится, а сразу перейдёт к следующей строке. И как потом действовать дальше? Хе-хе? Горе-программизд, документацию читать не пробовал? Варианты: 1. Ждать в цикле с DoEvent. 2. Событие завершения написать. ЗЫ. Да, пробовал. Не поверишь - получилось. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2016, 09:36 |
|
|
start [/forum/topic.php?fid=45&msg=39373440&tid=1612856]: |
0ms |
get settings: |
11ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
41ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
2ms |
others: | 363ms |
total: | 509ms |
0 / 0 |