Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Хранимые процедуры и функции.doc
Скачиваний:
8
Добавлен:
24.09.2019
Размер:
22.57 Mб
Скачать

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

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

В вышеуказанном примере объявляются две переменные типа int(11)id и num, инициированные значением 0, и три текстовые переменные – name, hello, temp, объявленные без дополнительной инициализации. Инициировать локальные переменные можно и позже при помощи параметра set.

Оператор declare может появляться только внутри блока beginend, область видимости объявленной переменной также ограничена этим блоком. Это означает, что в разных блоках beginend могут быть объявлены переменные с одинаковыми именами, и действовать они будут только в рамках данного блока, не пересекаясь с переменными других блоков (см. пример ниже).

В вышеуказанном примере переменная var объявляется сначала со значением abc во внешнем блоке beginend, после чего во вложенном блоке объявляется вторая переменная var со значением def, которая экранирует первую переменную.

Однако переменная, объявленная во внешнем блоке beginend, будет доступна во вложенном блоке, если не будет объявлена экранирующая ее переменная (см. пример ниже).

Обратное неверно: переменная, объявленная во вложенном блоке, недоступна во внешнем (см. пример ниже).

Как видно из вышеуказанного примера, вызов оператора select var во внешнем блоке beginend приводит к ошибке, т. к. время жизни переменной var ограничено ее блоком, и после выхода из этого блока ее существование прекращается.

В заключение следует отметить, что не допускается и повторное объявление переменной в рамках одного блока begin…end (см. пример ниже). Это приводит к возникновению ошибки 1331: “Повторное объявление переменной”.

1.4. Присвоение значения локальной переменной

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

  • оператор set;

  • оператор select…into…from.

В следующем примере оператор set присваивает переменной var значение 100, а второй оператор set увеличивает значение переменной var на единицу.

set var = 100;

set var = var + 1;

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

select id, testdate into x, y from test limit 1;

в этом примере id и testdate являются полями таблицы test, а x и y – локальными переменными хранимой процедуры или функции.

1.5. Форматирование временного интервала

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

Х дней Y часов Z минут W секунд

В приведенном ниже примере представлено возможное решение задачи. Следует обратить внимание, что при создании хранимой функции параметр second не может предваряться атрибутами in, out, inout.

Как видно из приведенного выше примера, из параметра second последовательно вычитаются дни, часы, минуты, которые заносятся в локальные переменные day, hour, minute соответственно. После чего результат собирается в конечную строку при помощи встроенной функции concat().

Функция concat(str1, str2, …) – возвращает строку, созданную путем объединения всех аргументов, количество которых не ограничено.

Пусть имеется таблица catalogs (см. пример ниже), содержащая три столбца:

  • id_catalog – целочисленный столбец, играющий роль первичного ключа таблицы;

  • name – текстовый столбец, содержащий названия элементов каталога;

  • putdate – поле типа datetime, в котором хранится время последнего обновления элемента каталога.

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

Функция timestampdiff() возвращает разницу между двумя датами в единицах измерения, указанных в первом аргументе. Функция доступна, начиная с версии MySQL 5.0. В более ранних версиях необходимо преобразовать обе даты к формату UNIXSTAMP (количество секунд, прошедших с полуночи 1 января 1970 года) при помощи функции from_unixtime() и вычесть полученные значения друг из друга.

Далее представлен более сложный пример – вычисляется разница между правками отдельных элементов каталога, и это достигается при помощи самообъединения таблицы catalogs. Для удобства таблица сортируется по первичному ключу id_catalog, и разница в правке вычисляется для двух соседних позиций.

Ряд значений, которые возвращает функция timestampdiff(), оказываются отрицательными, поэтому при помощи функции abs() возвращается абсолютное значение результата.