Опубликован: 07.05.2010 | Доступ: свободный | Студентов: 3039 / 328 | Оценка: 4.49 / 4.19 | Длительность: 25:58:00
Лекция 19:

Хранимые процедуры

< Лекция 18 || Лекция 19: 123 || Лекция 20 >

События и оператор POST_EVENT

В хранимых процедурах и триггерах сервер InterBase позволяет посылать заинтересованным клиентам извещение о наступлении какого-либо события. Делается это командой POST_EVENT:

POST_EVENT "Имя_события"

Пример:

POST_EVENT "Ups_Sorry"

Имя события может быть строкой или текстовой переменной, содержащей имя события.

Клиентская программа должна зарегистрировать на сервере те события, которые ее интересуют, чтобы получать их. Сделать это в клиентском приложении проще всего с помощью компонента TIBEventAlert, который находится на вкладке Samples Палитры компонентов, либо с помощью компонента TIBEvents, если вы для работы с БД пользуетесь компонентами с вкладки InterBase.

Суть работы с этими компонентами проста:

Вначале в свойстве Database вы выбираете компонент базы данных, например TDatabase или TIBDatabase, в зависимости от того, каким механизмом доступа к БД вы пользуетесь. Компонент базы данных должен быть подключен к серверу (подробнее об этом в следующих лекциях).

Далее вы дважды щелкаете по свойству Events, которое имеет тип TStrings, и в открывшемся списке вписываете интересующие вас события.

Затем вы переводите свойство Registered в True.

Потом требуется перейти на вкладку Events инспектора объектов и сгенерировать событие OnEventAlert, в котором можете написать какое-либо сообщение или действие. Параметр EventName будет содержать имя случившегося события. Например:

If EventAlert = 'Ups_Sorry' then
   ShowMessage('Извините, но кто то удалил вашу запись!');

Параметр EventCount содержит количество событий, произошедших на сервере, а изменяемый параметр CancelAlerts позволяет отказаться от выдачи дальнейших сообщений, для этого нужно присвоить ему значение True.

Изменения и удаления хранимых процедур

Изменение существующей процедуры делается командой ALTER PROCEDURE. Синтаксис этой команды ничем не отличается от синтаксиса команды CREATE PROCEDURE. Это "мягкий" способ изменения процедуры, который обычно применяют для добавления новых входных или выходных параметров. Более надежным способом считается удаление старой процедуры и создание новой, с таким же именем.

Удаление процедуры производится командой

DROP PROCEDURE <имя_процедуры>
<имя_процедуры> - это просто имя существующей процедуры без всяких параметров.

Пример:

DROP PROCEDURE MyProc;

Разумеется, изменять или удалять процедуру может только администратор SYSDBA или пользователь, создавший эту процедуру. Причем при изменении или удалении, процедура не должна находиться в использовании.

Примеры создания и вызова хранимых процедур

Далее следуют примеры процедур, которые необходимо выполнять в Interactive SQL. Убедитесь, что сервис InterBase включен, загрузите IBConsole, войдите в базу данных First и вызовите окно Interactive SQL. Выполним следующий пример:

/* Переопредилим терминатор: */
SET TERM ^;
/* Создаем процедуру, которая будет добавлять новые записи
   в таблицу Table_Firma: */
CREATE PROCEDURE Firma_Insert
  (F VARCHAR(20), I VARCHAR(20), O VARCHAR(20))
AS
BEGIN
  INSERT INTO TABLE_FIRMA(FAMILIYA, IMYA, OTCHESTVO)
         VALUES(:F, :I, :O);
END^
SET TERM ;^
COMMIT;

/* Сразу же применим полученную процедуру для ввода значений: */
EXECUTE PROCEDURE Firma_Insert
  ('Иванов', 'Иван', 'Иванович');
EXECUTE PROCEDURE Firma_Insert
  ('Петров', 'Петр', 'Петрович');
EXECUTE PROCEDURE Firma_Insert
  ('Николаев', 'Николай', 'Николаевич');
COMMIT;

Данный пример создает выполняемую процедуру Firma_Insert, которая добавляет в таблицу Table_Firma указанные в параметре фамилию, имя и отчество. После создания процедуры мы трижды вызвали ее для добавления новых записей. Подобного рода процедуры нередко используют для предварительной проверки значений, переданных в качестве параметров. Эти значения можно изменить перед добавлением или исправлением записи, или отказаться добавлять запись, если какое-то значение не удовлетворяет нужному условию. Подобный подход позволяет организовать довольно гибкую систему бизнес-логики, которая будет выполняться на стороне сервера.

Следующий пример создаст процедуру выборки:

/* Переопределяем терминатор: */
SET TERM ^;
/* Создаем процедуру: */
CREATE PROCEDURE Firma_Select
RETURNS (F VARCHAR(20), I VARCHAR(20), O VARCHAR(20))
AS
BEGIN
  /* С помощью цикла получаем все строки таблицы: */
  FOR SELECT * FROM TABLE_FIRMA
  INTO :F, :I, :O
  DO SUSPEND;
END^
SET TERM ;^
COMMIT;

/* Вызовем полученную процедуру командой SELECT: */
SELECT * FROM Firma_Select;

Эта процедура не изменяет данных, она только получает все записи из таблицы Table_Firma, и выводит их одна за другой. В результате, в нижнем окне Interactive SQL мы получим следующую картину:

Результат действий процедуры выборки Firma_Select

Рис. 19.1. Результат действий процедуры выборки Firma_Select

Как видите, и первая и вторая процедуры выполнили свою задачу. Мы получили такой же набор данных, как из обычной таблицы. В качестве полей здесь выступают выходные параметры F, I и O.

Иногда хранимые процедуры применяют для получения набора из данных, которые вообще не хранятся в базе данных. Вот пример такой процедуры:

SET TERM ^;
CREATE PROCEDURE PrimerProc(I INTEGER)
RETURNS (K INTEGER, V VARCHAR(25))
AS
BEGIN
  K = 0;
  WHILE (K < I) DO
  BEGIN
    K = K + 1;
    V = 'Строка № ' || K;
    SUSPEND;
  END
END^
SET TERM ;^
COMMIT;

/* Вызываем полученную процедуру: */
SELECT * FROM PrimerProc(5);

Обратите внимание, в процедуре имеется входной параметр I, в котором мы можем передать целое число, определяющее количество строк в полученном наборе данных. Также у нас имеется два выходных параметра K и V, соответственно, целое число и строка из 25 символов. Эти параметры сформируют поля полученного набора данных.

Далее мы обнуляем целую переменную и вызываем цикл WHILE, который будет выполняться до тех пор, пока переменная K будет меньше входящего параметра. В цикле мы вначале прибавляем к этой переменной единицу, после чего формируем строку типа "Строка № 1". При этом мы используем знак конкатенации (объединения) строк "||", а в качестве второй подстроки подставляем целое число, которое хранится в переменной K. Происходит неявное преобразование типов данных. Только не забывайте, целое число можно преобразовать в строку, но не наоборот! Далее мы вызываем оператор SUSPEND, который помещает полученную строку в набор данных. Цикл будет продолжаться столько раз, сколько мы укажем во входящем параметре процедуры. Когда мы вызовем эту процедуру оператором SELECT, то получим следующий результат:

Результат работы процедуры PrimerProc

Рис. 19.2. Результат работы процедуры PrimerProc

Теперь, открыв в дереве серверов IBConsole базу данных First, и выделив подраздел Stored Procedures, вы увидите три созданных хранимых процедуры, которые в дальнейшем можно вызывать неоднократно.

< Лекция 18 || Лекция 19: 123 || Лекция 20 >
Евгений Медведев
Евгений Медведев

В лекции №2 вставляю модуль данных. При попытке заменить name на  fDM выдает ошибку: "The project already contains a form or module named fDM!". Что делать? 

Анна Зеленина
Анна Зеленина

При вводе типов успешно сохраняется только 1я строчка. При попытке ввести второй тип вылезает сообщение об ошибке "project mymenu.exe raised exception class EOleException with message 'Microsoft Драйвер ODBC Paradox В операции должен использоваться обновляемый запрос'.