- •Раздел 2 проектирование серверной части приложения баз данных
- •Тема 2.1 sql-сервер InterBase и его основные компоненты
- •Тема 2.2 Физическая организация базы данных InterBase.
- •Тема 2.3 Создание базы данных.
- •Тема 2.4 Домены
- •Создание домена.
- •Тема 2.5 Создание таблиц
- •Определение ключей и ссылочных целостностей.
- •Тема 2.6 Работа с индексами.
- •Тема 2.7 Добавление, изменение, удаление записей
- •Добавление записей
- •Изменение записей.
- •Тема 2.8 Работа с просмотрами view.
- •Тема 2.9 Работа с хранимыми процедурами.
- •Изменение и удаление хранимых процедур
- •Алгоритмический язык хранимых процедур.
- •Тема 2.10 Работа с триггерами
- •Создание триггеров.
- •Тема 2.11 Использование генераторов.
Алгоритмический язык хранимых процедур.
1. Объявление локальных переменных. Локальные переменные, если они определены в процедуре, хранятся от начала выполнения процедуры и до ее окончания. Вне процедуры локальные переменные неизвестны и попытка обращения к ним вызовет ошибку. Локальные переменные используют для хранения промежуточных значений.
Формат объявления локальных переменных:
DECLARE VARIABLE <имя переменной><тип данных>
2. Операторные скобки BEGIN … END, ограничивают тело процедуры и могут использоваться для указания границ составного оператора.
3. Условный оператор IF … THEN … ELSE … имеет такой же формат, как и в Object Pascal.
4. Оператор SELECT используется в хранимой процедуре для выдачи единичной строки. По сравнению с синтаксисом обычного оператора SELECT , в процедурный оператор добавляется предложение
INTO: переменная [, переменная …]
Оно служит для указания переменных или выходных параметров, в которые должны быть записаны значения, возвращаемые оператором SELECT (те результирующие значения, которые перечисляются после ключевого слова SELECT).
Пример:
Приводимый ниже оператор SELECT возвращает среднее и сумму по столбцу KOLVO и записывает их соответственно в AVG_KOLVO и SUM_KOLVO, которые могут быть как локальными переменными, так и выходными параметрами процедуры. Расчет среднего и суммы по столбцу KOLVO производится только для записей, у которых значение столбца TOVAR совпадает с содержимым IN_TOVAR (входной параметр или локальная переменная).
SELECT AVG(KOLVO), SUM(KOLVO)
FROM RASHOD
WHERE TOVAR=:IN_TOVAR
INTO :AVG_KOLVO, :SUM_KOLVO;
5. Оператор SUSPEND передает в вызывающее приложение значения результирующих параметров (перечисленных после слова RETURNS в описании функции), имеющие место на момент выполнения SUSPEND. После этого выполнение хранимой процедуры приостанавливается. Когда от оператора SELECT, вызывающего приложение, приходит запрос на следующее значение выходных параметров, выполнение хранимой процедуры возобновляется.
6. Оператор FOR SELECT DO имеет следующий формат:
FOR
<оператор SELECT>
DO
<оператор>;
Алгоритм работы оператора FOR SELECT DO заключается в следующем. Выполняется оператор SELECT, и для каждой строки полученного результирующего набора данных выполняется оператор, следующий за словом DO. Этим оператором часто бывает SUSPEND, который приводит к возврату выходных параметров в вызывающее приложение.
Примеры:
1. Процедура выдает все расходы конкретного товара, определяемого содержимым входного параметра IN_TOVAR.
CREATE PROCEDURE RASHOD_TOVARA(IN_TOVAR VARCHAR(20))
RETURNS (OUT_DAT DATE, OUT_POKUP VARCHAR(20),
OUT_KOLVO INTEGER) AS
BEGIN
FOR SELECT DAT_RASH, POKUP, KOLVO
FROM RASHOD
WHERE TOVAR =:IN_TOVAR
INTO :OUT_DAT, :OUT_POKUP, :OUT_KOLVO
DO
SUSPEND;
END
Сначала выполняется оператор SELECT, который возвращает дату расхода, наименование покупателя и количество расхода товара для каждой записи, у которой столбец TOVAR содержит значение, идентичное значению во входном параметре IN_TOVAR. Указанные значения записываются в выходные параметры (соответственно OUT_DAT, OUT_POKUP, OUT_KOLVO). После выдачи каждой записи результирующего НД выполняется оператор SUSPEND. Он возвращает значения выходных параметров вызвавшему приложению и приостанавливает выполнение процедуры до запроса следующей порции выходных параметров от вызывающего приложения.
Такая процедура является процедурой выбора, поскольку она может возвращать множественные значения входных параметров в вызывающее приложение.
2.Процедура POK_LIST возвращает имена всех покупателей, которые сделали покупки товара IN_TOVAR в количестве, превосходящем средний размер покупки по этому товару. В случае если наименование покупателя пустое, вместо имени покупателя выводится “Покупателя нет”.
CREATE PROCEDURE POK_LIST(IN_TOVAR VARCHAR(20))
RETURNS (POK VARCHAR(20)) AS
DECLARE VARIABLE AVG_KOLVO INTEGER;
BEGIN
SELECT AVG(KOLVO)
FROM RASHOD
WHERE TOVAR =:IN_TOVAR
INTO :AVG_KOLVO;
FOR SELECT POKUP
FROM RASHOD
WHERE KOLVO >:AVG_KOLVO
INTO :POK
DO
BEGIN
IF (:POK IS NULL) THEN
POK = “Покупателя нет”;
SUSPEND;
END
END
7. Оператор WHILE … DO имеет такой формат:
WHILE (<условие>) DO <оператор>
В цикле проверяется выполнение условия; если оно истинно, выполняется оператор. Цикл продолжается до тех пор, пока условие не перестанет выполняться.
8. Оператор EXIT инициирует прекращение выполнения процедуры и выход в вызывающее приложение.
Пример:
Процедура MAX_VALUE возвращает максимум из двух чисел, передаваемых как входные параметры; в случае, если одно из чисел имеет значение NULL, процедура завершается (в этом случае выходной параметр содержит значение NULL)
CREATE PROCEDURE MAX_VALUE(A INTGER, B INTEGER)
RETURNS(M_V INTEGER) AS
BEGIN
IF (:A IS NULL OR :B IS NULL) THEN
EXIT;
IF (:A > :B) THEN
M_V = :A;
ELSE
M_V = :B;
END
9. Оператор EXECUTE PROCEDURE вызывает другую хранимую процедуру.
EXECUTE PROCEDURE имя [входной параметр [,входной параметр …]] ;
[RETURNING_VALUES [выходной параметр [,выходной параметр …]] ;
Пример:
Перепишем приведенную выше процедуру POK_LIST таким образом, чтобы из ее тела вызывалась другая процедура, AVG_KOLVO,возвращающая среднее количество отпущенного товара:
CREATE PROCEDURE AVG_KOLVO (TVR VARCHAR (20))
RETURNS (OUT_AVG_KOLVO INTEGER)
AS
BEGIN
SELECT AVG(KOLVO)
FROM RASHOD
WHERE TOVAR =:TVR
INTO :OUT_AVG_KOLVO;
SUSPEND;
END
CREATE PROCEDURE POK_LIST1 (IN_TOVAR VARCHAR (20))
RETURNS(POK VARCHAR (20)) AS
DECLARE VARIABLE AVG_KOLVO INTEGER;
BEGIN
EXECUTE PROCEDURE AVG_KOLVO(:IN_TOVAR)
RETURNING_VALUES :AVG_KOLVO
FOR SELECT POKUP
FROM RASHOD
WHERE KOLVO >:AVG_KOLVO
INTO :POK
DO
BEGIN
IF (:POK IS NULL) THEN
POK = “Покупателя нет”;
SUSPEND;
END
END