Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Подземелье Магов
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  23:31[Войти] | [Зарегистрироваться]

Некоторые решения с применением генераторов

Кубанычбек Тажмамат уулу
дата публикации 30-05-2001 00:00

Некоторые решения с применением генераторов

Итак, поставлены две задачи для Interbase:
  1. 1. Отслеживать процентовку долго выполняющейся хранимой процедуры.
  2. 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] [Генераторы]

 Обсуждение материала нет сообщений
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования