Некоторые решения с применением генераторов.
Раздел Подземелье Магов |
Итак, поставлены две задачи для Interbase:
- 1. Отслеживать процентовку долго выполняющейся хранимой процедуры.
- 2. Прерывать безопасным способом слишком долго выполняющуюся процедуру.
- а) с применением специально написанных пользовательской функции, передающей "третьему лицу" значение отслеживаемого параметра.
- б) использование генератора.
Зададим три генератора:
генератор автоинкрементного поля для таблицы 1 CREATE GENERATOR j_gen; SET GENERATOR j_gen to 0;
генератор для процентовки CREATE GENERATOR PROC_gen; SET GENERATOR PROC_gen to 0;
генератор, обозначающий код ошибки (по ходу решаем задачу 2) CREATE GENERATOR error_code_gen; SET GENERATOR error_code_gen to 0;
Определим три процедуры
SET TERM ^ ; /* процедура заполнения таблицы 1 */ CREATE PROCEDURE FILL (x INTEGER) RETURNS (error_code INTEGER) /*Возвращающей код ошибки*/ AS declare variable j integer; BEGIN BEGIN /*Сначала обнулим безопасным способом код ошибки*/ error_code=gen_id(error_code_gen, 0); WHILE (error_code<0) DO error_code=gen_id(error_code_gen, 1); j=0; WHILE (j<x) DO begin /*вот здесь и обрабатывается "событие" ошибки, так как значение генератора доступно и другому пользователю*/ error_code=gen_id(error_code_gen, 0); if (error_code<0) then begin Exit; end /*автоинкремент и вставка*/ j=gen_id(j_gen, 1); INSERT INTO T1(F1) VALUES (:j); end END END ^ /*процедура, процентовка которй отслеживается*/ CREATE PROCEDURE TEST_PROC (x INTEGER) RETURNS (error_code INTEGER) AS declare variable i integer; declare variable j integer; declare variable maxj integer; declare variable f1 integer; BEGIN BEGIN /*Сначала обнулим безопасным способом код ошибки*/ error_code=gen_id(error_code_gen, 0); WHILE (error_code<0) DO error_code=gen_id(error_code_gen, 1); /*Сначала обнулим безопасным способом процентовку*/ i=gen_id(PROC_gen, 0); WHILE (I<>0) DO i=gen_id(PROC_gen, -1); /*Узнаем, чему равно 100%*/ SELECT COUNT(F1) FROM T1 INTO :MAXj; j=0; /*Началась процентовка*/ FOR SELECT F1 FROM T1 INTO :f1 do begin /*вот здесь и обрабатывается "событие" ошибки, так как значение генератора доступно и другому пользователю*/ error_code=gen_id(error_code_gen, 0); if (error_code<0) then begin Exit; end j=j+1; IF (j>(i*maxj/100)) THEN BEGIN /*Еще раз напомним, что значение генератора видно другим пользователям до вездесущего COMMIT-а*/ i=gen_id(PROC_gen, 1); END INSERT INTO T2(F1) VALUES (:f1); END END END ^ /* Процедура-останавливалка. Запускается другим пользователем */ CREATE PROCEDURE MAKE_ERROR (do_error_code INTEGER) /*Задаваемый код ошибки*/ RETURNS (error_code INTEGER) AS BEGIN BEGIN /*Сначала обнулим безопасным способом код ошибки*/ error_code=gen_id(error_code_gen, 0); WHILE (error_code<0) DO error_code=gen_id(error_code_gen, 1); /*Установим значение кода ошибки*/ WHILE (error_code<>do_error_code) DO error_code=gen_id(error_code_gen, -1); END END ^ SET TERM ;^
В архиве приведен подробный пример приложения на Delphi, вызывающего, эти процедуры. Отображается линейка процентовки, которую можно остановить.
Скачать архив (12 K)
Кубанычбек Тажмамат уулу,
30 мая 2001г.
Специально для