Spec-Zone.ru › MySQL 8.4

15.5 Подготовленные запросы

  • 15.5.1 Оператор PREPARE
  • 15.5.2 Оператор EXECUTE
  • 15.5.3 Оператор DEALLOCATE PREPARE

MySQL 8.4 поддерживает подготовленные запросы на стороне сервера. Эта поддержка использует преимущества эффективного двоичного протокола клиент-сервер. Использование подготовленных запросов с заполнительными значениями параметров имеет следующие преимущества:

  • Меньшая нагрузка при разборе запроса каждый раз при его выполнении. Обычно приложения базы данных обрабатывают большие объемы почти идентичных запросов, с изменениями только в значениях литералов или переменных в таких клаузах, как WHERE для запросов и удалений, SET для обновлений и VALUES для вставок.

  • Защита от атак SQL-инъекций. Значения параметров могут содержать неэкранированные символы кавычек и разделителей SQL.

В следующих разделах приводится обзор характеристик подготовленных запросов:

  • Подготовленные запросы в приложениях

  • Подготовленные запросы в SQL-скриптах

  • Операторы PREPARE, EXECUTE и DEALLOCATE PREPARE

  • Разрешенный SQL-синтаксис в подготовленных запросах

Подготовленные запросы в приложениях

Вы можете использовать подготовленные запросы на стороне сервера через интерфейсы клиентских программ, включая для программ на C, для программ на Java и для программ, использующих технологии .NET. Например, API на C предоставляет набор вызовов функций, составляющих его API подготовленных запросов. См. . Другие языковые интерфейсы могут поддерживать подготовленные запросы, использующие двоичный протокол, связывая клиентскую библиотеку на C, одним из примеров является mysqli расширение, доступное в PHP 5.0 и более поздних версиях.

Подготовленные запросы в SQL-скриптах

Доступен альтернативный SQL-интерфейс для подготовленных запросов. Этот интерфейс не так эффективен, как использование двоичного протокола через API подготовленных запросов, но не требует программирования, так как доступен непосредственно на уровне SQL:

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

  • Вы можете использовать его из любой программы, которая может отправлять SQL-запросы на сервер для выполнения, например, программа-клиент mysql.

  • Вы можете использовать его, даже если клиент использует старую версию клиентской библиотеки.

SQL-синтаксис для подготовленных запросов предназначен для таких ситуаций:

  • Для проверки работы подготовленных запросов в вашем приложении перед его кодированием.

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

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

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

Операторы PREPARE, EXECUTE и DEALLOCATE PREPARE

SQL-синтаксис для подготовленных запросов основан на трех SQL-операторах:

  • PREPARE готовит запрос к выполнению (см. Раздел 15.5.1, «Оператор PREPARE»).

  • EXECUTE выполняет подготовленный запрос (см. Раздел 15.5.2, «Оператор EXECUTE»).

  • DEALLOCATE PREPARE освобождает подготовленный запрос (см. Раздел 15.5.3, «Оператор DEALLOCATE PREPARE»).

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

Первый пример показывает, как создать подготовленный запрос, используя строковый литерал для задания текста запроса:

mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql> SET @a = 3;
mysql> SET @b = 4;
mysql> EXECUTE stmt1 USING @a, @b;
+------------+
| hypotenuse |
+------------+
|          5 |
+------------+
mysql> DEALLOCATE PREPARE stmt1;

Второй пример аналогичен, но задает текст запроса как переменную пользователя:

mysql> SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql> PREPARE stmt2 FROM @s;
mysql> SET @a = 6;
mysql> SET @b = 8;
mysql> EXECUTE stmt2 USING @a, @b;
+------------+
| hypotenuse |
+------------+
|         10 |
+------------+
mysql> DEALLOCATE PREPARE stmt2;

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

mysql> USE test;
mysql> CREATE TABLE t1 (a INT NOT NULL);
mysql> INSERT INTO t1 VALUES (4), (8), (11), (32), (80);

mysql> SET @table = 't1';
mysql> SET @s = CONCAT('SELECT * FROM ', @table);

mysql> PREPARE stmt3 FROM @s;
mysql> EXECUTE stmt3;
+----+
| a  |
+----+
|  4 |
|  8 |
| 11 |
| 32 |
| 80 |
+----+

mysql> DEALLOCATE PREPARE stmt3;

Подготовленный запрос специфичен для сессии, в которой он был создан. Если вы завершите сессию, не выполнив освобождение ранее подготовленного запроса, сервер освободит его автоматически.

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

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

Разрешенный SQL-синтаксис в подготовленных запросах

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

ALTER {INSTANCE | TABLE | USER}
ANALYZE
CALL
CHANGE {REPLICATION SOURCE TO | REPLICATION FILTER}
CHECKSUM
COMMIT
{CREATE | DROP} INDEX
{CREATE | DROP | RENAME} DATABASE
{CREATE | DROP | RENAME} TABLE
{CREATE | DROP | RENAME} USER
DEALLOCATE PREPARE
DROP VIEW
DELETE
DO
EXECUTE
FLUSH
GRANT {ROLE}
INSERT
INSTALL PLUGIN
KILL
OPTIMIZE
PREPARE
REPAIR TABLE
REPLACE
REPLICA {START | STOP}
RESET
REVOKE {ALL | ROLE}
SELECT
SET ROLE
SHOW {BINLOG EVENTS | BINARY LOGS | BINARY LOG STATUS | CHARACTER SETS | COLLATIONS | DATABASES | ENGINES |
      ERRORS | EVENTS | FIELDS | FUNCTION CODE | FUNCTION STATUS | GRANTS | KEYS | OPEN TABLES |
      PLUGINS | PRIVILEGES | PROCEDURE CODE | PROCEDURE STATUS | PROCESSLIST | PROFILE | PROFILES |
      RELAYLOG EVENTS | REPLICAS | REPLICA STATUS | STATUS | PROCEDURE STATUS | TABLE STATUS | TABLES |
      TRIGGERS | VARIABLES | WARNINGS}
SHOW CREATE { DATABASE | EVENT | FUNCTION | PROCEDURE | TABLE | TRIGGER | USER | VIEW}
TRUNCATE
UNINSTALL PLUGIN
UPDATE
Примечание

CREATE TABLE ... START TRANSACTION не поддерживается в подготовленных запросах.

Другие операторы не поддерживаются.

Для соответствия стандарту SQL, который гласит, что операторы диагностики не могут быть подготовлены, MySQL не поддерживает следующие операторы как подготовленные запросы:

  • SHOW COUNT(*) WARNINGS

  • SHOW COUNT(*) ERRORS

  • Операторы, содержащие ссылку на системную переменную warning_count или error_count.

Как правило, операторы, не разрешенные в подготовленных SQL-запросах, также не разрешены в хранимых программах. Исключение делается в Разделе 27.8, «Ограничения на хранимые программы».

Изменения метаданных таблиц или представлений, на которые ссылаются подготовленные запросы, обнаруживаются и вызывают автоматическую повторную подготовку запроса при его следующем выполнении. Более подробную информацию см. в Разделе 10.10.3, «Кэширование подготовленных запросов и хранимых программ».

Для аргументов клаузы LIMIT можно использовать заполнительные значения при использовании подготовленных запросов. См. Раздел 15.2.13, «Оператор SELECT».

В подготовленных операторах CALL, используемых с PREPARE и EXECUTE, поддержка заполнителей для параметров OUT и INOUT доступна начиная с MySQL 8.4. См. Раздел 15.2.1, «Оператор CALL», для примера и обходного решения для более ранних версий. Заполнительные значения можно использовать для параметров IN независимо от версии.

SQL-синтаксис для подготовленных запросов не может быть использован вложенным образом. То есть, оператор, переданный в PREPARE, не может сам быть оператором PREPARE, EXECUTE или DEALLOCATE PREPARE.

SQL-синтаксис для подготовленных запросов отличается от использования вызовов API подготовленных запросов. Например, вы не можете использовать функцию API C для подготовки оператора PREPARE, EXECUTE или DEALLOCATE PREPARE.

SQL-синтаксис для подготовленных запросов может быть использован внутри хранимых процедур, но не в хранимых функциях или триггерах. Однако курсор не может быть использован для динамического оператора, который подготовлен и выполнен с помощью PREPARE и EXECUTE. Оператор для курсора проверяется во время создания курсора, поэтому оператор не может быть динамическим.

SQL-синтаксис для подготовленных запросов не поддерживает многострочные операторы (то есть несколько операторов в одной строке, разделенных символами ;).

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

CLIENT_MULTI_RESULTS можно включить при вызове, либо явно передав флаг CLIENT_MULTI_RESULTS, либо неявно передав CLIENT_MULTI_STATEMENTS (что также включает CLIENT_MULTI_RESULTS). Дополнительную информацию см. в разделе 15.2.1, «Оператор CALL».

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/sql-prepared-statements.html

Spec-Zone.ru

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