Кубанычбек Тажмамат уулу дата публикации 30-05-2001 00:00 Некоторые решения с применением генераторов
Итак, поставлены две задачи для Interbase:
- 1. Отслеживать процентовку долго выполняющейся хранимой процедуры.
- 2. Прерывать безопасным способом слишком долго выполняющуюся процедуру.
Для задачи 1 потенциально возможны без изменения исходного кода
Interbase два решения:
- а) с применением специально написанных пользовательской функции, передающей "третьему лицу" значение отслеживаемого параметра.
- б) использование генератора.
Генераторы - уникальные объекты Interbase. Уникальны они тем, что
их значение изменяется и без вездесущего COMMIT. Стандартные и
нестандартные способы применения генераторов описаны Д. Кузьменко
в статье http://ib.demo.ru/DevInfo/generator.htm .
Получается, что их можно использовать в качестве глобальных
целочисленных переменных сервера. Итак, пусть даны две таблицы
CREATE TABLE T1(
F1 INTEGER
);
CREATE TABLE T2(
F1 INTEGER
);
Отследить надо процесс перекачивания данных из первой таблицы во вторую.
Конечно, этот пример слишком прост, так как для этой цели не обязательно
использовать процедуры, перекачать можно простым INSERT-ом. Но на
этом простом примере отработаем приемы, которые пригодятся в
дальнейшем для отслеживания длительных процедур, выполняющих
сложные расчеты и т.д.
Зададим три генератора:
генератор автоинкрементного поля для таблицы 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, вызывающего,
эти процедуры. Отображается линейка процентовки, которую можно остановить.
Скачать архив Gen.zip (12 K)
Кубанычбек Тажмамат уулу, 30 мая 2001г.
Специально для Королевства Delphi
[INTERBASE] [Генераторы]
Обсуждение материала нет сообщений |