Сайт о телевидении

Сайт о телевидении

» » Хранимые процедуры mysql. MySQL хранимые процедуры

Хранимые процедуры mysql. MySQL хранимые процедуры

От автора: чего это вы спите на рабочем месте! Вы не спите, а ждете, пока СУБД выполнит запрос? Так ее нужно разогнать. Хранимые процедуры MySQL применяли? Не знаете как? Ну, тогда просыпайтесь, потому что сейчас мы будем рассматривать как раз эту тему.

Что за процедуры еще?

Если у вас фобия насчет медицинских процедур, то данные структуры «не из той темы». Так что можно не бояться. А если серьезно, то хранимые процедуры – это удобная и полезная для «здоровья» СУБД вещь. Их еще называют «хранимыми функциями MySQL», но это не совсем точное определение. Хотя давайте разбираться со всем по порядку.

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

В MySQL вызов хранимой процедуры означает, что вписанные в ее код запросы обработаются лишь наполовину. И то, если будет изменены значения их параметров. Но не все так идеально. Опишем сначала положительные стороны использования процедур:

Инкапсуляция функциональности – весь код хранится в одном месте, что облегчает доступ к нему для других приложений. В этом хранимые процедуры схожи с программными функциями.

Изоляция доступа к данным – все пользователи получают доступ не к строкам таблиц, а только к хранимым процедурам. Что в свою очередь повышает уровень защищенности всех данных.

Повышение скорости работы сервера – за счет кэширования и объединения запросов.

В MySQL хранимые процедуры в теории являются структурами, относящимся к более «высоким материям» — программированию СУБД. Так что мы с вами (как профессионалы) хоть потихоньку, но . Но вернемся к процедурам, и опишем негативные стороны их использования:

Нагрузка на сервер БД повышается – большая часть кода процедур выполняется на стороне сервера. Данная СУБД построена по модели «клиент-сервер», в которой задействованы несколько устройств.

Усложняется манипуляция данными – при разработке приложений придется прописывать часть кода и на клиентской стороне.

Усложняется процесс переноса БД на другие рельсы (СУБД).

Процедуры в phpMyAdmin

Для начала рассмотрим применение в MySQL хранимых процедур на примере phpMyAdmin. Таким образом нам будет легче разобраться с этим типом структур. Стартуем!

Запускаем программную оболочку, справа выбираем тестовую БД. У меня таковой является база world. Затем в главном меню сверху переходим по вкладке «Процедуры». Здесь жмем на «Добавить процедуру».

После этого появится окно диалога «Добавить процедуру». Заполняем в ней все указанные на снимке поля. Указываем имя процедуры, тип. В графе «Определение» вводим учетную запись пользователя, и в комментариях (необязательно) указываем для себя, что это всего лишь пример хранимой процедуры.

Уже на этом этапе мы знакомимся с особенностями синтаксиса создания хранимых процедур MySQL. В поле «Определение» прописываем тело структуры. Обратите внимание, что выполняемый запрос находится между ключевыми словами BEGIN и END:

BEGIN SELECT "HELLO, WORD!"; END

BEGIN

SELECT "HELLO, WORD!" ;

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

Для окончания создания нашей первой процедуры жмем внизу «Ок». После этого программа выводит «зелененькое» сообщение об удачном выполнении запроса. Его код представлен ниже. В MySQL хранимые процедуры и функции создаются с помощью специальной команды CREATE PROCEDURE. Но об этом позже.

Теперь запустим созданную структуру на выполнение. Для этого в разделе «Процедуры» нажимаем ссылку «Выполнить». Но что это за безобразие! Куда делся наш любимый «зелененький»? Почему программа «ругается» и «кричит», что ей не хватает выделенной памяти?

Куда смотрел автор данной публикации…! Извините, немного запутался. Ведь автор – это я . Спокойствие, сейчас все исправим! Такая ошибка возникает из-за того, что в главном конфигурационном файле значение параметра thread_stack оставлено без изменений. По умолчанию для каждого потока выделяется 128 Kb. Выделенного лимита оперативки для выполнения простых запросов вполне хватает, но для процедур мало.

Это еще раз доказывает, что на выполнение триггеров и хранимых процедур в MySQL тратится больше ресурсов.

Перейдите в конфигурационный файл my.ini, и увеличьте лимит оперативки, установленной для каждого потока, до 256 kb. Теперь еще раз запустите на выполнение созданную процедуру. В этот раз все прошло как надо, и программа вернула результат без ошибки.

Обратите внимание, что для вызова используется команда CALL с указанием имени процедуры и принимаемых параметров (в скобках).

Более сложный пример

Но все же phpMyAdmin по своим возможностям больше подходит для быстрого составления процедур. А для разработки в MySQL хранимой процедуры с динамическим количеством аргументов (например) потребуется более удобное ПО. Почему:

phpMyAdmin не хочет нормально «понимать» процедуры, созданные не через специальный конструктор.

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

Если вы внимательно следите за моими публикациями и выполняете все прописанные в них «пожелания», то у вас должен уже стоять MySQL Administrator. В привязку к нему осталось скачать MySQL Query Browser по этой ссылке. Эти две программы лучше использовать вместе: в первой создавать процедуры, а в другой тестировать их. Поехали:

Слева вверху переходим через вкладку «Catalog».

Выбираем нужную БД, и в верхнем меню жмем на «Stored procedures», а внизу на «Create Stored Proc»

В появившемся окне редактора вводим код процедуры и жмем «Execute SQL».

CREATE DEFINER=`roman`@`localhost` PROCEDURE `proc5`() BEGIN declare a int; set a="SELECT COUNT(*) FROM city as a"; if(a > 1000)THEN SELECT "<1000"; ELSE SELECT ">1000"; END IF; END

CREATE DEFINER = ` roman ` @ ` localhost ` PROCEDURE ` proc5 ` ()

BEGIN

declare a int ;

set a = "SELECT COUNT(*) FROM city as a" ;

if (a > 1000 ) THEN

SELECT "<1000" ;

ELSE

SELECT ">1000" ;

END IF ;

Вы, наверное, заметили, что мы не передаем никаких значений внутрь процедуры. Кроме этого в MySQL может быть неизвестное количество параметров в хранимой процедуре, которые затем можно передать через новые объявления переменных, расположенные внутри циклов.

Для запуска процедуры заходим в MySQL Query Browser. Сначала вводим свою учетку и пароль, а затем слева в «Object Explorer» находим папку с нужной базой. Остальная очередность действия показана на следующем снимке.

Запуск процедуры в PHP

Теперь рассмотрим, как происходит в PHP вызов хранимой процедуры MySQL. Для этого нам придется немного «перекроить» код нашего предыдущего примера. Мы добавим в процедуру параметр на вывод, а также изменим код запроса:

CREATE DEFINER=`root`@`localhost` PROCEDURE `proc6`(out col decimal) BEGIN SELECT COUNT(*) into col FROM city; END

CREATE DEFINER = ` root ` @ ` localhost ` PROCEDURE ` proc6 ` (out col decimal )

BEGIN

SELECT COUNT (* ) into col FROM city ;

Для вызова из файла PHP процедуры и вывода результата будем использовать возможности класса PDOStatement, созданного специально для работы с БД через SQL

Этот класс реализован сравнительно недавно, и поддерживается PHP, начиная с версии 5.1.0. Советую перед использованием проверить используемую версию языка c помощью встроенной функции phpversion().

Наиболее общая разница между процедурами и функциями заключается в том, что они вызываются по-разному и для разных целей:

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

Синтаксис для рутинного создания несколько отличается для процедур и функций:

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

    • Чтобы вызвать хранимую процедуру, используйте CALL statement . Чтобы вызвать хранимую функцию, обратитесь к ней в выражении. Функция возвращает значение во время оценки выражения.

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

      Задание параметра IN, OUT или INOUT действительна только для ПРОЦЕДУРЫ. Для функции FUNCTION параметры всегда считаются параметрами IN.

    Если ключевое слово не задано перед именем параметра, оно по умолчанию является параметром IN. Параметрам для сохраненных функций не предшествуют IN, OUT или INOUT. Все параметры функции рассматриваются как параметры IN.

Чтобы определить хранимую процедуру или функцию, используйте CREATE PROCEDURE или CREATE FUNCTION соответственно:

CREATE PROCEDURE proc_name () routine_body CREATE FUNCTION func_name () RETURNS data_type // diffrent routine_body

Расширение MySQL для хранимой процедуры (не функций) состоит в том, что процедура может генерировать набор результатов или даже несколько наборов результатов, которые вызывающий выполняет так же, как результат инструкции SELECT. Однако содержимое таких наборов результатов не может быть использовано непосредственно в выражении.

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

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

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

Готовые заявления SQL (PREPARE, EXECUTE, DEALLOCATE PREPARE) могут использоваться в хранимых процедурах, но не в хранимых функциях или триггерах. Таким образом, хранимые функции и триггеры не могут использовать Dynamic SQL (где вы строите операторы как строки, а затем выполняете их). (Динамический SQL в MySQL хранимых процедурах)

Еще несколько интересных отличий между FUNCTION и STORED PROCEDURE:

    Функции обычно используются для вычислений, где as процедуры обычно используются для выполнения бизнес-логики.

    Функции Не могут повлиять на состояние базы данных (Заявления, которые делают явное или неявное совершение или откат, запрещены в функции) В то время как Хранимые процедуры могут влиять на состояние базы данных, используя фиксацию и т.д.
    refrence: J.1. Ограничения на хранимые процедуры и триггеры

    Функции не могут использовать FLUSH , тогда как Хранимые процедуры могут выполнять.

    Внутри хранимой функции или триггера не разрешается изменять таблицу, которая уже используется (для чтения или записи) оператором, вызывающим функцию или триггер. Хороший пример: Как обновить ту же таблицу при удалении в MYSQL?

Примечание : хотя некоторые ограничения обычно применяются к хранимым функциям и триггерам, но не к хранимым процедурам, эти ограничения применяются к хранимым процедурам, если они вызываются из хранимой функции или триггера. Например, хотя вы можете использовать FLUSH в хранимой процедуре, такую ​​хранимую процедуру нельзя вызывать из хранимой функции или триггера.

Проще говоря, хранимые процедуры («ХП») - это сохраненные в базе данных процедуры (написанные с помощью SQL и других управляющих операторов), которые могут быть выполнены движком баз данных и вызваны из программного кода, который с этим движком работает. »»» Читать полностью

Хранимые процедуры в MySQL и PHP. Часть 2

Тэйлор Рен (Taylor Ren ), 03.01.2014

Создание хранимой процедуры в MySQL

Поскольку ХП хранятся на сервере, то и создавать их рекомендуется непосредственно на сервере, т.е. не следует использовать PHP или другие языки программирования для выполнения SQL-команд по созданию хранимых процедур.

Давайте рассмотрим, как создать ХП на сервере MySQL, как создать пользователя для нее и как назначить ему привилегии на запуск нашей ХП. Затем проверим корректность результата. Для этого я воспользуюсь MySQL Workbench . Можно использовать и другие программы (например, PHPMyAdmin). Вы можете выбрать тот инструментарий, который вам больше подходит.

Допустим, наша таблица выглядит так:

CREATE TABLE `salary` (`empid` int(11) NOT NULL, `sal` int(11) DEFAULT NULL, PRIMARY KEY (`empid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Для нашего служащего, которому нужна статистическая информация по зарплатам (средняя, максимальная, минимальная и т.п.) из этой таблицы, мы создадим пользователя "tr" следующим образом:

CREATE USER "tr"@"localhost" IDENTIFIED BY "mypass";

Теперь назначим этому пользователю единственную привилегию EXECUTE в той схеме, где находится таблица salary:

Grant execute on hris.* to tr@`%`

Мы можем убедиться в том, что назначили нужную привилегию, открыв «Users and Privileges» в MySQL Bench:

Теперь создадим саму ХП следующим образом:

DELIMITER $$ CREATE PROCEDURE `avg_sal`(out avg_sal decimal) BEGIN select avg(sal) into avg_sal from salary; END

После выполнения этой команды в MySQL Workbench, будет создана готовая к использованию ХП avg_sal . Она возвращает среднюю зарплату по таблице salary .

Чтобы проверить, действительно ли пользователь tr может запустить ХП и не имеет доступа к таблице salary , нам нужно переподключиться к серверу MySQL, залогинившись как tr . В MySQL Workbench это можно сделать создав другое соединение и указав нужного пользователя и его пароль .

После подключения из под tr , первое, что мы замечаем, - это то, что пользователь вообще не видит каких-либо таблиц, видит только ХП:

Очевидно, что пользователь tr не может обращаться ни к одной из таблиц (а значит, не может видеть и подробную информацию о зарплатах из таблицы salary), но может запустить созданную нами ХП, которая вернет ему среднюю зарплату по компании:

Call avg_sal(@out); select @out;

Будет отображена средняя зарплата.

Итак, мы выполнили всю подготовительную работу: создали пользователя, назначили ему привилегии, создали ХП и протестировали ее. Теперь посмотрим, как вызывать эту ХП из PHP .

Вызов хранимой процедуры из PHP

При использовании PDO вызов ХП довольно прост. Вот соответствующий PHP-код:

$dbms = "mysql"; // Замените следующие параметры соединения на соответствующие вашему окружению: $host = "192.168.1.8"; $db = "hris"; $user = "tr"; $pass = "mypass"; $dsn = "$dbms:host=$host;dbname=$db"; $cn=new PDO($dsn, $user, $pass); $q=$cn->exec("call avg_sal(@out)"); $res=$cn->query("select @out")->fetchAll(); print_r($res);

Переменная $res содержит среднюю зарплату по таблице salary . Теперь пользователь может производить дальнейшую обработку вывода с помощью PHP.

Выводы

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

Кроме того, мы продемонстрировали основные шаги в создании хранимых процедур, пользователей и назначения соответствующих привилегий, показали, как ХП вызываются из PHP.

Эта статья не покрывает всю тему хранимых процедур. Некоторые важные аспекты, такие как параметры ввода/вывода , управляющие операторы, курсоры, полный синтаксис и др. не были освещены в этой краткой статье.

Если вы заинтересовались, пожалуйста, оставьте здесь свой комментарий. Если нужно, мы будем рады предложить более глубокие статьи о таком полезном и мощном аспекте MySQL, как хранимые процедуры.

Тэйлор Рен

Тэйлор - свободный разработчик веб- и десктопных приложений , проживающий в Сужоу в восточном Китае. Начинал со средств разработки Borland (C++Builder, Delphi), опубликовал книгу по InterBase. С 2003 является сертифицированным экспертом Borland. Затем переключился на веб-разработку в типичной конфигурации LAMP. Позднее начал работать с jQuery, Symfony, Bootstrap, Dart и т.д.

Предыдущие публикации:

Внимание! Данная работа построена на основе перевода раздела «17.1. Stored Routines and the Grant Tables» описания ПО MySQL 5.0.19, «Reference Manual. It documents MySQL 5.0 through 5.0.19. Document generated on: 2006-01-23 (revision:995)»
``Сначала прочти все, а потом пробуй примеры"

Хранимые процедуры представляют собой набор команд SQL, которые могут компилироваться и храниться на сервере. Таким образом, вместо того, чтобы хранить часто используемый запрос, клиенты могут ссылаться на соответствующую хранимую процедуру. Это обеспечивает лучшую производительность, поскольку данный запрос должен анализироваться только однажды и уменьшается трафик между сервером и клиентом. Концептуальный уровень можно также повысить за счет создания на сервере библиотеки функций.

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

Хранимые программы (процедуры и функции) поддерживаются в MySQL 5.0. Хранимые процедуры - набор SQL -выражений, который может быть сохранен на сервере. Как только это сделано, клиенту уже не нужно повторно передавать запрос, а требуется просто вызвать хранимую программу.

Это может быть полезным тогда, когда:

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

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

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

MySQL следует в синтаксисе за SQL:2003 для хранимых процедур, который уже используется в IBM"s DB2.

От слов к делу…

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

Начиная с MySQL 5.0.3 требуются следующие привилегии:

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

ALTER ROUTINE необходимы для изменения или удаления процедур. Эта привилегия автоматически назначается создателю процедуры (функции)

EXECUTE привилегия потребуется для выполнения подпрограммы. Тем не менее, автоматически назначается создателю процедуры (функции). Также, по умолчанию, SQL SECURITY параметр для подпрограммы DEFINER , который разрешает пользователям, имеющим доступ к БД вызывать подпрограммы, ассоциированные с этой БД.

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

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

Начиная с MySQL 5.0.1, загруженная процедура или функция связана с конкретной базой данных. Это имеет несколько смыслов:

  • Когда подпрограмма вызывается, то подразумевается, что надо произвести вызов USE db_name (и отменить использование базы, когда подпрограмма завершилась, и база больше не потребуется)
  • Вы можете квалифицировать обычные имена с именем базы данных. Это может быть использовано, чтобы ссылаться на подпрограмму, которая - не в текущей базе данных. Например, для выполнения хранимой процедуры p или функции f которые связаны с БД test , вы можете сказать интерпретатору команд так: CALL test.p() или test.f() .
  • Когда база данных удалена, все загруженные подпрограммы связанные с ней тоже удаляются. В MySQL 5.0.0, загруженные подпрограммы - глобальные и не связанны с базой данных. Они наследуют по умолчанию базу данных из вызывающего оператора. Если USE db_name выполнено в пределах подпрограммы, оригинальная текущая БД будет восстановлена после выхода из подпрограммы (Например текущая БД db_11 , делаем вызов подпрограммы, использующей db_22 , после выхода из подпрограммы остается текущей db_11)

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

CREATE PROCEDURE - создать хранимую процедуру.

CREATE FUNCTION - создать хранимую функцию.

Синтаксис:

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

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

параметр_процедуры:
[ IN | OUT | INOUT ] имя_параметра тип
параметр_функции:
имя_параметра тип

тип:
Любой тип данных MySQL

характеристика:
LANGUAGE SQL
| DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT "string"

тело_подпрограммы:
Правильное SQL выражение.

Рассмотрим все на практике.

Сначала создадим хранимую процедуру следующим запросом:

CREATE PROCEDURE `my_proc`(OUT t INTEGER(11))
NOT DETERMINISTIC
SQL SECURITY INVOKER
COMMENT ""
BEGIN
select val1+val2 into "t" from `my` LIMIT 0,1;
END;

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

После этого вызовем ее:

CALL my_proc(@a);
SELECT @a;

Для отделения внутреннего запроса от внешнего всегда используют разделитель отличный от обычно (для задания используют команду DELIMITER <строка/символ>)

Вот еще один пример с учетом всех требований.

Mysql> delimiter //
mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
-> BEGIN
-> SELECT COUNT(*) INTO param1 FROM t;
-> END;
-> //

mysql> delimiter ;
mysql> CALL simpleproc(@a);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @a;
+------+
| @a |
+------+
| 3 |
+------+
1 row in set (0.00 sec)

Весь процесс можно пронаблюдать на рисунке ниже:

Триггеры

Поддержка триггеров появилась в MySQL начиная с версии 5.0.2.

Триггер - поименованный объект БД, который ассоциирован с таблицей и активируемый при наступлении определенного события, события связанного с этой таблицей.

Например, нижеприведенный код создает таблицу и INSERT триггер. Триггер суммирует значения, вставляемые в один из столбцов таблицы.

Mysql> CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
Query OK, 0 rows affected (0.03 sec)
mysql> CREATE TRIGGER ins_sum BEFORE INSERT ON account
-> FOR EACH ROW SET @sum = @sum + NEW.amount;
Query OK, 0 rows affected (0.06 sec)

Объявим переменную sum и присвоим ей значение 1. После этого при каждой вставке в таблицу account значение этой переменной будет увеличивать согласно вставляемой части.

Замечание . Если значение переменной не инициализировано, то триггер работать не будет!

Синтаксис создания триггера

CREATE

TRIGGER имя_триггера время_триггера событие_срабатывания_триггера
ON имя_таблицы FOR EACH ROW выражение_выполняемое_при_срабатывании_триггера

Если с именем триггера и именем пользователя все понятно сразу, то о «времени триггера» и «событии» поговорим отдельно.

время_триггера

Определяет время свершения действия триггера. BEFORE означает, что триггер выполнится до завершения события срабатывания триггера, а AFTER означает, что после. Например, при вставке записей (см. пример выше) наш триггер срабатывал до фактической вставки записи и вычислял сумму. Такой вариант уместен при предварительном вычислении каких-то дополнительных полей в таблице или параллельной вставке в другую таблицу.

событие_срабатывания_триггера

Здесь все проще. Тут четко обозначается, при каком событии выполняется триггер.

  • INSERT: т.е. при операциях вставки или аналогичных ей выражениях (INSERT, LOAD DATA, и REPLACE)
  • UPDATE: когда сущность (строка) модифицирована
  • DELETE: когда запись удаляется (запросы, содержащие выражения DELETE и/или REPLACE)

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

  • SHOW PROCEDURE STATUS - позволяет просмотреть список имеющихся хранимых процедур. Правда просматривать этот список не очень удобно, т.к. по каждой процедуре выдается информация об имени БД, к которой процедура принадлежит, ее типе, учетной записи, от имени которой была создана процедура, о дате создания и изменения процедуры и т.д. И все-таки, если вам необходимо посмотреть, какие процедуры у вас есть, то стоит воспользоваться этим оператором.

  • SHOW CREATE PROCEDURE имя_процедуры - позволяет получить информацию о конкретной процедуре, в частности просмотреть ее код. Вид для просмотра также не очень удобный, но разобраться можно.

Попробуйте оба оператора в действии, чтобы знать, как это выглядит. А теперь рассмотрим более удобный вариант получения подобной информации. В системной базе данных MySQL есть таблица proc, где и хранится информация о процедурах. Так вот мы может сделать SELECT-запрос к этой таблице. Причем, если мы создадим привычный запрос:

SELECT * FROM mysql.proc//

То получим нечто такое же нечитабельное, как и при использовании операторов SHOW. Поэтому мы будем создавать запросы с условиями. Например, если мы создадим вот такой запрос:

SELECT name FROM mysql.proc//

То получим имена всех процедур всех баз данных, имеющихся на сервере. Нас, например, на данный момент интересуют только процедуры базы данных shop, поэтому изменим запрос:

Вот теперь мы получили то, что хотели:

Если же мы хотим посмотреть только тело конкретной процедуры (т.е. от begin до end), то мы напишем такой запрос:

И увидим вполне читабельный вариант:

Вообще, чтобы извлекать из таблицы proc необходимую вам информацию, надо просто знать, какие столбцы она содержит, а для этого можно воспользоваться знакомым нам с первого урока оператором describe имя_таблицы , в нашем случае describe mysql.proc . Правда, вид у нее тоже не очень читабельный, поэтому приведем здесь названия наиболее востребованных столбцов:

  • db - имя БД, в которую сохранена процедура.

  • name - имя процедуры.

  • param_list - список параметров процедуры.

  • body - тело процедуры.

  • comment - комментарий к хранимой процедуре.

Столбцы db, name и body мы уже использовали. Запрос, извлекающий параметры процедуры sum_vendor составьте самостоятельно. А вот про комментарии к хранимым процедурам мы сейчас поговорим подробнее.

Комментарии вещь крайне необходимая, ведь через какое-то время мы может забыть, что делает та или иная процедура. Конечно, по ее коду можно восстановить нашу память, но зачем? Гораздо проще сразу при создании процедуры указать, что она делает, и тогда, даже по прошествии долгого времени, обратившись к комментариям, мы сразу вспомним, зачем эта процедура создавалась.

Создавать комментарии крайне просто. Для этого сразу после списка параметров, но еще до начала тела хранимой процедуры указываем ключевое слово COMMENT "здесь комментарий" . Давайте удалим нашу процедуру sum_vendor и создадим новую, с комментарием:

CREATE PROCEDURE sum_vendor(i INT) COMMENT "Возвращает сумму товара по идентификатору поставщика." begin DROP VIEW IF EXISTS report_vendor; CREATE VIEW report_vendor AS SELECT incoming.id_vendor, magazine_incoming.id_product, magazine_incoming.quantity, prices.price, magazine_incoming.quantity*prices.price AS summa FROM incoming, magazine_incoming, prices WHERE magazine_incoming.id_product= prices.id_product AND magazine_incoming.id_incoming= incoming.id_incoming; SELECT SUM(summa) FROM report_vendor WHERE id_vendor=i; end //


А теперь сделаем запрос к комментарию процедуры:

Вообще-то, чтобы добавить комментарий, вовсе не обязательно было удалять старую процедуру. Можно было отредактировать имеющуюся хранимую процедуру с помощью оператора ALTER PROCEDURE . Давайте посмотрим, как это сделать, на примере процедуры ins_cust из прошлого урока. Эта процедура вводит информацию о новом покупателе в таблицу Покупатели (customers). Давайте добавим комментарий к этой процедуре:

ALTER PROCEDURE ins_cust COMMENT "Вводит информацию о новом покупателе в таблицу Покупатели."//

И сделаем запрос к комментарию, чтобы проверить:

В нашей базе данных всего две процедуры, и комментарии к ним кажутся излишними. Не ленитесь, обязательно пишите комментарии. Представьте, что в нашей базе данных десятки или сотни процедур. Сделав нужный запрос, вы без труда узнаете, какие процедуры есть и что они делают и поймете, что комментарии - это не излишества, а экономия вашего времени в будущем. Кстати, а вот и сам запрос:

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