Spec-Zone.ru › MySQL 8.4

27.8 Ограничения на хранимые программы

  • SQL-запросы, запрещённые в хранимых процедурах

  • Ограничения для хранимых функций

  • Ограничения для триггеров

  • Конфликты имён в хранимых процедурах

  • Учет репликации

  • Учет отладки

  • Неподдерживаемый синтаксис стандарта SQL:2003

  • Учет одновременного доступа в хранимых процедурах

  • Ограничения планировщика событий

  • Хранимые процедуры и триггеры в NDB Cluster

Эти ограничения применяются к функциям, описанным в Главе 27, Хранимые объекты.

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

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

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

SQL-запросы, запрещённые в хранимых процедурах

Хранимые процедуры не могут содержать произвольные SQL-запросы. Следующие запросы запрещены:

  • Запросы блокировки LOCK TABLES и UNLOCK TABLES.

  • ALTER VIEW.

  • LOAD DATA и LOAD XML.

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

  • Как правило, запросы, запрещённые в подготовленных SQL-запросах, также запрещены в хранимых программах. Список поддерживаемых запросов в виде подготовленных запросов см. в Разделе 15.5, “Подготовленные запросы”. Исключения составляют SIGNAL, RESIGNAL и GET DIAGNOSTICS, которые не допускаются в виде подготовленных запросов, но допускаются в хранимых программах.

  • Поскольку локальные переменные доступны только во время выполнения хранимой программы, ссылки на них запрещены в подготовленных запросах, созданных внутри хранимой программы. Область видимости подготовленного запроса — текущая сессия, а не хранимая программа, поэтому запрос может быть выполнен после завершения программы, в этот момент переменные больше не будут в области видимости. Например, SELECT ... INTO local_var не может использоваться в виде подготовленного запроса. Это ограничение также относится к параметрам хранимых процедур и функций. См. Раздел 15.5.1, “Запрос PREPARE”.

  • В рамках всех хранимых программ (хранимых процедур и функций, триггеров и событий) анализатор рассматривает BEGIN [WORK] как начало блока BEGIN ... END. Для начала транзакции в данном контексте используйте START TRANSACTION вместо этого.

Ограничения для хранимых функций

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

  • Операторы, которые выполняют явное или неявное подтверждение или откат транзакции. Поддержка этих операторов не требуется стандартом SQL, который указывает, что каждый поставщик СУБД может решить, разрешать их или нет.

  • Операторы, которые возвращают набор результатов. Это включает запросы SELECT, у которых нет условия INTO var_list, а также другие запросы, такие как SHOW, EXPLAIN и CHECK TABLE. Функция может обработать набор результатов либо с помощью SELECT ... INTO var_list, либо используя курсор и операторы FETCH. См. Раздел 15.2.13.1, “Запрос SELECT ... INTO”, и Раздел 15.6.6, “Курсоры”.

  • Запросы FLUSH.

  • Хранимые функции не могут быть использованы рекурсивно.

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

  • Если вы ссылаетесь на временную таблицу несколько раз в хранимой функции под разными псевдонимами, возникает ошибка Can't reopen table: 'tbl_name', даже если ссылки находятся в разных операторах внутри функции.

  • Запросы HANDLER ... READ, которые вызывают хранимые функции, могут вызывать ошибки репликации и запрещены.

Ограничения для триггеров

Для триггеров применяются следующие дополнительные ограничения:

  • Триггеры не активируются действиями внешних ключей.

  • При использовании репликации на основе строк, триггеры на реплике не активируются запросами, исходящими от источника. Триггеры на реплике активируются при использовании репликации на основе запросов. Дополнительную информацию см. в Разделе 19.5.1.36, “Репликация и триггеры”.

  • Оператор RETURN запрещён в триггерах, которые не могут возвращать значение. Чтобы немедленно выйти из триггера, используйте оператор LEAVE.

  • Триггеры запрещены для таблиц в базе данных mysql. Они также запрещены для таблиц INFORMATION_SCHEMA и performance_schema. Эти таблицы фактически являются представлениями, и триггеры не разрешены для представлений.

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

Конфликты имён в хранимых процедурах

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

CREATE PROCEDURE p (i INT)
BEGIN
  DECLARE i INT DEFAULT 0;
  SELECT i FROM t;
  BEGIN
    DECLARE i INT DEFAULT 1;
    SELECT i FROM t;
  END;
END;

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

  • Локальная переменная имеет приоритет над параметром процедуры или столбцом таблицы.

  • Параметр процедуры имеет приоритет над столбцом таблицы.

  • Локальная переменная во внутреннем блоке имеет приоритет над локальной переменной во внешнем блоке.

Поведение, при котором переменные имеют приоритет над столбцами таблиц, не является стандартным.

Учёт репликации

Использование хранимых процедур может вызвать проблемы с репликацией. Эта проблема обсуждается далее в Разделе 27.7, «Журналирование двоичных данных хранимых программ».

Опция --replicate-wild-do-table=db_name.tbl_name относится к таблицам, представлениям и триггерам. Она не относится к хранимым процедурам и функциям, или событиям. Для фильтрации операторов, работающих с последними объектами, используйте одну или несколько опций --replicate-*-db.

Учёт отладки

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

Неподдерживаемый синтаксис из стандарта SQL:2003

Синтаксис хранимых процедур MySQL основан на стандарте SQL:2003. Следующие элементы из этого стандарта в настоящее время не поддерживаются:

  • UNDO обработчики

  • FOR циклы

Учёт параллельности хранимых процедур

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

Для максимальной параллельности хранимые функции должны минимизировать побочные эффекты; в частности, обновление таблицы внутри хранимой функции может снизить параллельные операции над этой таблицей. Хранимая функция приобретает блокировки таблицы перед выполнением, чтобы избежать несоответствия в двоичном журнале из-за несовпадения порядка выполнения операторов и их появления в журнале. При использовании журналирования на основе операторов записываются операторы, вызывающие функцию, а не операторы, выполняемые внутри функции. В результате хранимые функции, обновляющие одни и те же основополагающие таблицы, не выполняются параллельно. В отличие от этого, хранимые процедуры не приобретают блокировки на уровне таблицы. Все операторы, выполняемые внутри хранимых процедур, записываются в двоичный журнал, даже для журналирования на основе операторов. См. Раздел 27.7, «Журналирование двоичных данных хранимых программ».

Ограничения планировщика событий

Следующие ограничения относятся к планировщику событий:

  • Имена событий обрабатываются без учёта регистра. Например, вы не можете иметь два события в одной базе данных с именами anEvent и AnEvent.

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

  • Операторы DDL над событиями запрещены, пока действует оператор LOCK TABLES.

  • Временные интервалы YEAR, QUARTER, MONTH и YEAR_MONTH при расчёте времени события решены в месяцах; любые другие интервалы — в секундах. Нет способа заставить события, запланированные на выполнение в одну и ту же секунду, выполняться в определённом порядке. Кроме того, из-за округления, характера многопоточных приложений и того факта, что требуется определённое ненулевое время для создания событий и сигнализации о их выполнении, события могут быть задержаны на 1 или 2 секунды. Однако время, показанное в таблице Information Schema EVENTS в столбце LAST_EXECUTED, всегда точно соответствует фактическому времени выполнения события с погрешностью в одну секунду. (См. также ошибку #16522.)

  • Каждое выполнение операторов, содержащихся в теле события, происходит в новом соединении; таким образом, эти операторы не влияют на счётчики операторов в данной пользовательской сессии на сервере, такие как Com_select и Com_insert, которые отображаются оператором SHOW STATUS. Однако такие счётчики обновляются в глобальном масштабе. (Ошибка #16422)

  • События не поддерживают даты после конца эпохи Unix; это примерно начало 2038 года. Такие даты специально не допускаются планировщиком событий. (Ошибка #16396)

  • Ссылки на хранимые функции, загружаемые функции и таблицы в предложениях ON SCHEDULE операторов CREATE EVENT и ALTER EVENT не поддерживаются. Такие ссылки недопустимы. (См. ошибку #22830 для получения дополнительной информации.)

Хранимые процедуры и триггеры в NDB Cluster

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

Любая хранимые процедура или триггер, взаимодействующая с таблицами MySQL Cluster, должна быть пересоздана путём выполнения соответствующих операторов CREATE PROCEDURE, CREATE FUNCTION или CREATE TRIGGER на каждом сервере MySQL, участвующем в кластере, где вы хотите использовать хранимую процедуру или триггер. Аналогично, любые изменения в существующих хранимых процедурах или триггерах должны быть выполнены явно на всех узлах Cluster SQL, используя соответствующие операторы ALTER или DROP на каждом сервере MySQL, обращающемся к кластеру.

Предупреждение

Не пытайтесь обойти эту проблему, преобразуя таблицы базы данных mysql для использования движка хранения NDB. Изменение системных таблиц в базе данных mysql не поддерживается и, скорее всего, приведёт к нежелательным результатам.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/stored-program-restrictions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API