Форум: "Базы";
Текущий архив: 2002.08.12;
Скачать: [xml.tar.bz2];
ВнизПрогрес выполнения процедуры Найти похожие ветки
← →
Kombat (2002-07-21 12:03) [0]Hi All! Есть процедура которая производит изменения в БД, процесс идет примерно 10 минут. Хотелось бы показате пользователю что он не завис)). Переносить всю логику в программу только из-за визуализации прогреса не хочется, замедлится работа. Какие есть методы отображения прогреса. Я думал об возможности использования генераторов (в процедуре увеличиваем его значение, а из программы читаем), но тогдакак наилучшим образом снимать значания генератора из программы, не хотелось бы завалить сервер постоянными SELECT GEN_ID ...
Какие есть еще пути решения этой проблемы?
Заранее благодарен.
← →
Lola (2002-07-21 12:13) [1]Можно вставить какой-нибудь компонент с анимацией. По-моему, это для 10 минут достаточно щадащий вариант.
← →
Kombat (2002-07-21 12:24) [2]к сожалению анимация не пройдет, просто сейчас обработка идет на 70000 записях, 5 минут, но дальше их будет много больше. Запуск в отдельном потоке не помогает, так как это будет ряд разных по тяжести процедур, который выполняются строго последовательно. Кроме того в процессе работы процедур пользователь и не должен ничего делать паралельно этому, ему просто нужно знать - закончится обработка до конца рабочего дня или уже сейчас можно шагать домой ))
← →
kaif (2002-07-21 14:24) [3]У меня возникла внезапная идея!
Я никогда так не делал, но это может оказаться гениально...
Сделай в своей хранимой процедуре SUSPEND и возвращай какое- нибудь увеличивающееся число:
CREATE PROCEDURE MY_HEAVY_PROCEDURE(...)
RETURNS(PROGRESS INTEGER)
AS
BEGIN
.... <Всякие тяжелве дела>
Иногда среди них:
IF <некое условие, например, шаг в 1000 записей> THEN
BEGIN
PROGRESS = PROGRESS + 1;
SUSPEND;
END
END
Теперь запускаешь свою тяжелую процедуру не с помощью
EXECUTE PROCEDURE MY_HEAVY_PROCEDURE,
а с помощью:
SELECT PROGRESS FROM MY_HEAVY_PROCEDURE
Процедура начинает просто медленно возвращать набор прогресса.
По-моему это сумасшедшая идея. Главное, IB это позволяет легко сделать.
Каждый следующий FETCH со стороны клиента сделает Update прогресс-бара. Процесс останется однопоточным, как ты хочешь и живым одновременно.
Я сейчас сам побегу такое попробую...
С уважением.
← →
Kombat (2002-07-21 14:32) [4]to kaif © прикольно. надо начинать пробовать такой вариант, может действительно получится. Спасибо.
Но другие варианты тоже еще принимаются.
← →
kaif (2002-07-21 14:38) [5]Для того, чтобы клиент выбирал один fetch за другим нужно сделать что-то вроде:
with MyHeavyProcQuery do
begin
Open;
while not Eof do
begin
ProgressBar.Position := FieldByName("PROGRESS").AsInteger;
Next;
end;
end;
← →
kaif (2002-07-21 14:42) [6]Более того. У меня еще идея. Если процедура будет возвращать не только PROGRESS, но и STATUS_MESSAGE VARCHAR(100), то можно будет извещать пользователя текстовыми сообщениями о этапах исполнения процедуры, чтобы если она рухнет или зависнет, тот знал, на где именно это произошло...
Отображать процесс можно даже не в ProgressBar в этом случае, а в Grid-е. Смотреться должно великолепно.
← →
Kombat (2002-07-21 14:45) [7]а не будет ли проблем из-за несогласованности временных затрат клиента и сервер - то клиент притормозит когда серевер будет обрабатывать пачку записей, то сервер будет ждать клиентского nextа?
← →
kaif (2002-07-21 14:48) [8]Но это же редко будет происходить! Допустим, раз в 10 сек. Я уверен, что на скорость это никак не повлияет. Сервер с клиентом взаимодействуют очень быстро (по сравнению с временем работы такой тяжелой процедуры). Нужно пробовать, конечно.
← →
Kombat (2002-07-21 14:56) [9]да, нужно пробовать, этим и займусь.
Это, во всяком случае, красивое решение, то что встречалось ранее сводилось к "ищи в IB API" - а твое должно по идее работать на любом сервере БД
← →
kaif (2002-07-21 16:36) [10]Насчет того, что под любым сервером сработает, я бы не спешил так думать. SUSPEND - фишка IB.
В любом случае сообщи, что получилось. Мне тоже интересно.
← →
Kombat (2002-07-21 19:25) [11]к сожалению не все получается как хотелость ((. Когда делаем Open IBQuery в проге, то отображение данных (прогрес процедуры) начинается после выполнения всей процедуры, т.е. после выполнения действий. А нужно чтоб после кажного suspend. Может я конечно что-то не так делаю, но помоему Open передаст данные Гриду после полного открытия
← →
Opuhshii (2002-07-22 10:05) [12]Используй генератор,.. ему не нужно Transaction Commit для изменения значения,... и соответственно через определенное время получаешь значения этого генератора,.. imho...
← →
Desdechado (2002-07-22 10:19) [13]2 kaif © (21.07.02 14:24)
> У меня возникла внезапная идея!
На самом деле идея не нова, но она не работает. Fetch начинается только ПОСЛЕ выполнения запроса, т.е. после создания сервером курсора для результата выборки.
Вариант с анимацией проще, хотя он и не показывает истинного прогресса операции, поскольку сервер сам не знает, сколько времени у него это займет.
← →
kaif (2002-07-22 14:06) [14]2 Desdechado © (22.07.02 10:19)
>Fetch начинается только ПОСЛЕ выполнения запроса
Жаль. Хотя у меня было такое опасение.
Тогда остается генератор + events (может быть)
или анимация.
Хотя я бы все-же посмотрел логику. Не стоит 10-20 мин. вещи запускать, ИМХО. Что-то в организации базы (самой задачи) не так... Если всего 70 тыс записей. Не миллионы же.
← →
kombat (2002-07-22 16:12) [15]70 тыс обрабатываются 3 минуты, но в другой задаче будет 1,5 млн., что на много больше. Пока работаем без визуализации прогреса, а потом буду пробовать вариант с генератором. Евент не пройдет так как он тоже работает в контексте транзакции.
← →
AlexSam (2002-07-22 16:56) [16]А процедура состоит из одного инсерта и т.д. или это набор инсертов или вообще курсор?
← →
kombat (2002-07-22 17:27) [17]это, в полном варианте набор процедур которые идут одна за другой (некоторые в IB, а те что нельзя реализовать по причине недостатка язиковых средств IB - в делфях). Это закрытие месяца в телекоммуникационной компании. Большинство процедур имеют такой вид - формируется таблица (условно): абонент-данные... Потом на основании этой таблицы производятся выборки, обновления и добавления в другие таблицы (начисления, счета и пр.). Большие таблицы - это трафик за месяц.
Кстати, может у кого есть опыт по написанию прог для телекоммуникаций? дайте контакт, может опытом обменяемся?
← →
AlexSam (2002-07-22 17:32) [18]А ты не можешь вызывать эти ХР из дельфей последовательно при этом визуально увеличивая прогресс-бар, но не коммитя транзакцию. Поверь, уменьшения быстродействия не будет.
← →
kombat (2002-07-22 17:35) [19]я сейчас в данном варианте вообще все в делфях обработываю. Просто процедура каждая будет работать 10 минут, долго ждать, и непонятно сколько
← →
Alexandr (2002-07-23 08:11) [20]а ночь для кого придумали?
← →
AlexSam (2002-07-23 09:40) [21]А может, имеет смысл поколотить объемы обраратываемых данных на несколько в XP?
← →
il (2002-07-23 09:51) [22]Я согласен с AlexSam.
Надо после выполнения очередной операции куда-нибудь писать что-то вроде "Отработала проца такая-то". И каждый раз читать это и выводить в грид. Думаю, что по сравнению с 10 минутами работы это будут небольшие потери времени. А если произойдет ошибка, то опять же ее можно будет вывести юзверю, короче, вести обычный протокол. К тому же можно добавить возможность контролировать процесс - остановить и возобновить. А анимация - это полумера, украшательство и не более.
← →
Desdechado (2002-07-23 10:13) [23]> а ночь для кого придумали?
во-во, и я о том же :)
> я сейчас в данном варианте вообще все в делфях обработываю.
дык, конечно, время выполнения на ПОРЯДОК больше при таком подходе. ты все в процедуру затолкай и почувствуй разницу
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.08.12;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.007 c