Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
all_lab.doc
Скачиваний:
47
Добавлен:
14.11.2019
Размер:
1.42 Mб
Скачать

8. Хранимые процедуры и функции

Хранимые процедуры и функции – это новая возможность, появившаяся в версии MySQL 5.0. Хранимая процедура представляет собой набор SQL-операторов, которые можно сохранять на сервере. После того, как это будет сделано, клиентам больше не придется повторно задавать одни и те же отдельные операторы; вместо этого они смогут обращаться к хранимой процедуре.

Ситуации, когда хранимые процедуры могут оказаться особенно полезными, таковы:

• многочисленные клиентские приложения написаны на разных языках или рабо-тают на различных платформах, но должны выполнять одинаковые операции с базами данных;

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

Хранимые процедуры помогают повысить эффективность, поскольку при их использовании объем пересылаемой между сервероми клиентом информации существенно снижается. Обратная сторона состоит в том, что это увеличивает нагрузку на систему сервера баз данных, так как в этом случае на стороне клиента (приложения) выполняется меньшая часть работы, а на стороне сервера – большая. Обязательно учитывайте это, если сразу большое количество клиентских машин (таких как Web-серверы) обслуживает только один или всего несколько серверов баз данных.

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

Синтаксис хранимой процедуры

Хранимые процедуры и функции представляют собой подпрограммы, создаваемые с помощью операторов CREATE PROCEDURE и CREATE FUNCTION. Подпрограмма является либо процедурой, либо функцией. Процедура вызывается с помощью оператора CALL и может только передавать значения обратно, используя выходные переменные. Функции могут возвращать скалярное значение и вызываются из оператора точно так же, как и любые другие функции (то есть, через указание имени функции). Хранимые процедуры могут вызывать другие хранимые процедуры.

В MySQL поддерживается самое удобное расширение, позволяющее использовать обычные операторы SELECT (применять курсоры и локальные переменные не нужно) внутри хранимой процедуры. Набор результатов такого запроса просто посылается непосредственно клиенту. Множественные операторы SELECT генерируют и множественные наборы результатов, поэтому клиенту следует использовать клиентскую библиотеку MySQL, поддерживающую множественные наборы результатов. Это означает, что клиентская библиотека должна быть из версии MySQL, по крайней мере, не ниже 4.1.

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

Обслуживание хранимых процедур

CREATE PROCEDURE и CREATE FUNCTION

CREATE PROCEDURE имя_хранимой_процедуры ([параметр[, ...]]) [характеристика ...] тело_процедуры

CREATE FUNCTION имя_хранимой__процедуры ([параметр[, ...]]) [RETURNS тип] [характеристика ...] тело_процедуры

параметр:

[ IN | OUT | INOUT ] имя_параметра тип

тип:

Любой допустимый тип данных MySQL

Характеристика:

LANGUAGE SQL

| [NOT] DETERMINISTIC

I SQL SECURITY {DEFINER I INVOKER}

| COMMENT 'строка1

тело процедуры:

Допустимый оператор (операторы) SQL процедуры

Конструкция RETURNS может быть определена только для FUNCTION. Она используется для указания типа результата функции, при этом в теле функции должен присутствовать оператор RETURN значение.

Список аргументов, заключенный в круглые скобки, должен присутствовать всегда. Если аргументы отсутствуют, следует использовать пустой список аргументов (). Каждый аргумент по умолчанию является аргументом IN. Чтобы по-другому определить аргумент, перед его названием укажите ключевое слово OUT или INOUT. Значения IN, OUT или INOUT являются допустимыми только для PROCEDURE.

Оператор CREATE FUNCTION используется в более ранних версиях MySQL для поддержки функций, определяемых пользователем. Однако стоит обратить внимание на то, что хранимые функции и функции, определяемые пользователем, разделяют одно и то же пространство имен.

Функция считается "детерминированной", если она всегда возвращает один и тот же результат для одних и тех же входных аргументов, в противном случае функция является "недетерминированной". В настоящее время характеристика DETERMINISTIC уже воспринимается, но еще не используется оптимизатором.

Характеристика SQL SECURITY может применяться для определения, должна ли процедура выполняться с использованием привилегий пользователя, создающего эту процедуру, или привилегий пользователя, ее вызывающего. Значение по умолчанию – DEFINER. Это новая функция в SQL:2OO3.

Конструкция COMMENT является расширением MySQL и может использоваться для описания хранимой процедуры. Такая информация отображается операторами SHOW CREATE PROCEDURE И SHOW CREATE FUNCTION.

MySQL разрешает, чтобы подпрограммы содержали DDL-операторы (такие как CREATE и DROP) и SQL-операторы транзакций (такие как COMMIT). Стандарт этого не требует, поэтому все будет зависеть от реализации.

Пример 1

Рассмотрим пример простой хранимой процедуры с аргументом OUT, которая считает количество строк в таблице t.

CREATE PROCEDURE simpleproc (OUT param1 INT)

BEGIN

SELECT COUNT(*) INTO param1 FROM t;

END

Вызов процедуры осуществляется с использованием следующей команды, при этом результат помещается в переменную @a.

CALL simpleproc(@a);

Просмотр результата работы процедуры:

SELECT @a;

Пример 2

Рассмотрим пример функции, которая принимает аргумент, выполняет операцию с помощью SQL-функции и возвращает результат:

CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50) RETURN CONCAT('Hello, ' , s , ' ! ' ) ;

Вызов функции:

SELECT hello('world') ;

Полученный результат:

Hello, world!

ALTER PROCEDURE и ALTER FUNCTION

ALTER {PROCEDURE | FUNCTION} имя_хранимой_процедуры [характеристика ...]

характеристика:

NAME новое имя

| SQL SECURITY {DEFINER | INVOKER}

| COMMENT 'строка'

Данный оператор можно использовать для переименования хранимой процедуры или функции, а также для изменения ее характеристик.

DROP PROCEDURE и DROP FUNCTION

DROP {PROCEDURE | FUNCTION} [IF EXISTS] имя_хранимой_процедуры

Данный оператор используется для удаления хранимой процедуры или функции, то есть указанная подпрограмма будет удалена с сервера.

Конструкция IF EXISTS является расширением MySQL. Она предотвращает появление ошибки, если процедура или функция не существует.

Оператор CALL

C A L L и м я _ х р а н и м о й _ п р о ц е д у р ы ( [ п а р а м е т р [ , . . . ] ] )

Оператор CALL используется для вызова процедуры, которая была ранее определена с помощью CREATE PROCEDURE.

Составной оператор BEGIN ... END

[метка_начала:] BEGIN

statement (s)

END [метка_конца]

Хранимые процедуры могут включать множественные операторы, благодаря составному оператору BEGIN.. .END.

Значения метка_начала и метка_конца, если оба заданы, должны быть одинаковыми.

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

Внутри подпрограммы можно объявлять и использовать переменные.

Локальные переменные DECLARE

DECLARE имя_переменной[,...] тип [DEFAULT значение]

Этот оператор используется для объявления локальных переменных. Контекст переменной ограничен блоком BEGIN . . . END.

Оператор установки переменных SET

SET и м я _ п е р е м е н н о й = в ы р а ж е н и е [ , и м я _ п е р е м е н н о й = в ы р а ж е н и е ] . . . ]

Оператор SET в хранимых процедурах представляет собой расширенную версию общего оператора SET. Запрашиваемые переменные могут быть как переменными, объявленными внутри процедуры, так и глобальными переменными сервера.

Оператор SET в хранимых процедурах вводится как часть существовавшего ранее синтаксиса SET, что разрешает использование расширенного синтаксиса: SET а=х, b=у,..., в котором могут смешиваться разные типы переменных (локально объявленные переменные, переменные сервера, а также глобальные и сеансовые переменные сервера). Также, благодаря этому, допустимым становится применение комбинаций локальных переменных и некоторых опций, имеющих смысл только для глобальных/системных переменных; в этом случае, опции принимаются, но игнорируются.

Оператор SELECT

SELECT имя_столбца[, . . . ] INTO имя_переменной[, . . . ] табличное_выражение

При таком синтаксисе SELECT выбранные столбцы сохраняются непосредственно в переменных. Поэтому извлечена может быть только одна единственная строка. Данный оператор также крайне полезен при его применении в сочетании с курсорами.

SELECT id, data INTO x,y FROM test.tl LIMIT 1;

Условия и обработчики

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

Условия DECLARE

DECLARE имя__условия CONDITION FOR значение_условия

значение__условия:

SQLSTATE [VALUE] значение_sqlstate

| Код ошибки__mysql

Данный оператор определяет условия, при которых потребуется определенный тип обработки. Он связывает имя с указанным условием ошибки.

Обработчики DECLARE

DECLARE тип_обработчика HANDLER FOR значение__условия[, . . .]

оператор_хранимой_процедуры

тип__обработчика:

CONTINUE

| EXIT

значение__условия:

SQLSTATE [VALUE] зачение_sqlstate

| имя_условия

| SQLWARNING

| NOT FOUND

| SQLEXCEPTION

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

Для обработчика CONTINUE выполнение текущей операции продолжается после выполнения оператора обработчика. Для обработчика EXIT выполнение текущего составного оператора BEGIN...END завершается.

Кроме значений SQLSTATE также поддерживаются коды ошибок MySQL.

Пример 3

Создадим таблицу:

CREATE TABLE test.t (s1 int , primary key (s1));

Создадим процедуру:

CREATE PROCEDURE handlerdemo()

BEGIN

DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;

SET @x = 1;

INSERT INTO test.t VALUES (1);

SET @x = 2;

INSERT INTO test.t VALUES (1);

SET @x = 3;

END;

Вызываем процедуру:

CALL handlerdemo ();

Смотрим результат работы процедуры:

SELECT @x;

Обратите внимание: @х равен 3, что указывает на то, что MySQL выполнил процедуру до конца. ЕСЛИ бы строка DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1; представлена не была, MySQL принял бы значение пути по умолчанию (EXIT) после второй неудачной из-за ограничения PRIMARY KEY попытки выполнить INSERT, и оператор SELECT @x возвратил бы значение 2.

Задания

Вариант 1

Создать БД, состоящую из таблиц АВТОР (Фамилия, имя, отчество, пол, дата рождения, телефон) и КНИГА (Название, цена, тематика, издательство, тираж). Дополнить при необходимости полями и таблицами, уточнить структуру.

Заполнить таблицы данными – 5-6 записей.

  1. Реализовать функцию, которая позволит по фамилии автора определить общий тираж книг.

  2. Реализовать функцию, которая позволит получить количество книг издательства (например, «Мир»).

  3. Создать логическую функцию, которая принимает значение истина, если существуют книги указанного издательства тиражом не менее определенного числа.

  4. Создать процедуру для увеличения на заданный процент цены книг заданного издательства. (Процентная ставка и наименование издательства указываются при вызове процедуры).

  5. Создать процедуру, которая определяет общую стоимость книг, изданных заданным автором в заданном издательстве. (Автор и наименование издательства указываются при вызове процедуры).

  6. В процедуре из задания 2 указать значения параметров по умолчанию (сохранить под другим именем).

Вариант 2

Создать БД, состоящую из таблиц РЕЙС (№ рейса, конечный пункт, дата вылета, продолжительность маршрута) и БИЛЕТ (Номер места, дата продажи, фамилия пассажира). Дополнить при необходимости полями и таблицами, уточнить структуру.

Заполнить таблицы данными – 5-6 записей.

  1. Реализовать функцию, которая позволит по номеру рейса определить общее число пассажиров.

  2. Реализовать функцию, которая позволит получить количество рейсов, вылетающих в Москву.

  3. Создать логическую функцию, которая принимает значение истина, если существует рейс, вылетающий в указанный город в определенный день.

  4. Создать процедуру для увеличения на заданный процент стоимости билетов до заданного пункта. (Процентная ставка и конечный пункт указываются при вызове процедуры).

  5. Создать процедуру, которая определяет количество пассажиров, вылетевших в заданный город в течение конкретного месяца. (Город и месяц указываются при вызове процедуры).

  6. В процедуре из задания 2 указать значения параметров по умолчанию (сохранить под другим именем).

Вариант 3

Создать БД, состоящую из таблиц БЛЮДО (Название, время приготовления, повар, общая калорийность) и КОМПОНЕНТ (Название, калорийность, стоимость 100 гр). Дополнить при необходимости полями и таблицами, уточнить структуру.

Заполнить таблицы данными – 5-6 записей.

  1. Реализовать функцию, которая позволит для указанного блюда определить его стоимость.

  2. Реализовать функцию, которая позволит получить количество компонентов с калорийностью > 300 ккал.

  3. Создать логическую функцию, которая принимает значение истина, если существует компонент, входящий в указанное блюдо и имеющее калорийность ниже заданного значения.

  4. Создать процедуру для увеличения на заданный процент стоимости блюд определенного типа. (Процентная ставка и тип блюда указываются при вызове процедуры).

  5. Создать процедуру, которая определяет общую калорийность блюд указанного типа, приготовленных заданным поваром. (Тип блюда и повар указываются при вызове процедуры).

  6. В процедуре из задания 2 указать значения параметров по умолчанию (сохранить под другим именем).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]