Spec-Zone.ru › MariaDB

Заявление PREPARE

Синтаксис

PREPARE stmt_name FROM preparable_stmt

Описание

Заявление PREPARE подготавливает запрос и присваивает ему имя, stmt_name, для дальнейшего обращения к нему. Имена запросов не чувствительны к регистру. preparable_stmt должно быть либо строковой константой, либо переменной пользователя (не локальной переменной, выражения SQL или подзапроса), содержащей текст запроса. Текст должен представлять собой единственное SQL-заявление, а не несколько. Внутри запроса символы "?" могут использоваться в качестве маркеров параметров, чтобы указать, где будут привязаны значения данных к запросу позже при его выполнении. Символы "?" не должны быть заключены в кавычки, даже если вы хотите привязать их к строковым значениям. Маркеры параметров могут использоваться только там, где должны быть выражения, а не для SQL-ключевых слов, идентификаторов и т. п.

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

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

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

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

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

CREATE PROCEDURE `test_stmt`(IN sql_text TEXT)
BEGIN
        DECLARE EXIT HANDLER FOR SQLEXCEPTION
        BEGIN
                SELECT CONCAT(sql_text, ' is not valid');
        END;
        SET @SQL := sql_text;
        PREPARE stmt FROM @SQL;
        DEALLOCATE PREPARE stmt;
END;

Функции FOUND_ROWS() и ROW_COUNT(), если вызваны сразу после EXECUTE, возвращают количество прочитанных или затронутых строк подготовленными запросами; однако, если они вызываются после DEALLOCATE PREPARE, они предоставляют информацию об этом запросе. Если подготовленный запрос генерирует ошибки или предупреждения, GET DIAGNOSTICS возвращает информацию о них. DEALLOCATE PREPARE не должен очищать область диагностики, если только это не приводит к ошибке.

Подготовленный запрос выполняется с помощью EXECUTE и высвобождается с помощью DEALLOCATE PREPARE.

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

ERROR 1461 (42000): Can't create more than max_prepared_stmt_count statements 
  (current value: 0)

Режим Oracle

MariaDB начиная с 10.3

В режиме Oracle начиная с MariaDB 10.3, PREPARE stmt FROM 'SELECT :1, :2' используется вместо ?.

Разрешённые заявления

MariaDB начиная с 10.6.2

Все заявления могут быть подготовлены, за исключением PREPARE, EXECUTE и DEALLOCATE / DROP PREPARE.

До этого не все заявления можно было готовить. Разрешены только следующие SQL-команды:

  • ALTER TABLE
  • ANALYZE TABLE
  • BINLOG
  • CACHE INDEX
  • CALL
  • CHANGE MASTER
  • CHECKSUM {TABLE | TABLES}
  • COMMIT
  • {CREATE | DROP} DATABASE
  • {CREATE | DROP} INDEX
  • {CREATE | RENAME | DROP} TABLE
  • {CREATE | RENAME | DROP} USER
  • {CREATE | DROP} VIEW
  • DELETE
  • DESCRIBE
  • DO
  • EXPLAIN
  • FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES | LOGS | STATUS | MASTER | SLAVE | DES_KEY_FILE | USER_RESOURCES | QUERY CACHE | TABLE_STATISTICS | INDEX_STATISTICS | USER_STATISTICS | CLIENT_STATISTICS}
  • GRANT
  • INSERT
  • INSTALL {PLUGIN | SONAME}
  • HANDLER READ
  • KILL
  • LOAD INDEX INTO CACHE
  • OPTIMIZE TABLE
  • REPAIR TABLE
  • REPLACE
  • RESET {MASTER | SLAVE | QUERY CACHE}
  • REVOKE
  • ROLLBACK
  • SELECT
  • SET
  • SET GLOBAL SQL_SLAVE_SKIP_COUNTER
  • SET ROLE
  • SET SQL_LOG_BIN
  • SET TRANSACTION ISOLATION LEVEL
  • SHOW EXPLAIN
  • SHOW {DATABASES | TABLES | OPEN TABLES | TABLE STATUS | COLUMNS | INDEX | TRIGGERS | EVENTS | GRANTS | CHARACTER SET | COLLATION | ENGINES | PLUGINS [SONAME] | PRIVILEGES | PROCESSLIST | PROFILE | PROFILES | VARIABLES | STATUS | WARNINGS | ERRORS | TABLE_STATISTICS | INDEX_STATISTICS | USER_STATISTICS | CLIENT_STATISTICS | AUTHORS | CONTRIBUTORS}
  • SHOW CREATE {DATABASE | TABLE | VIEW | PROCEDURE | FUNCTION | TRIGGER | EVENT}
  • SHOW {FUNCTION | PROCEDURE} CODE
  • SHOW BINLOG EVENTS
  • SHOW SLAVE HOSTS
  • SHOW {MASTER | BINARY} LOGS
  • SHOW {MASTER | SLAVE | TABLES | INNODB | FUNCTION | PROCEDURE} STATUS
  • SLAVE {START | STOP}
  • TRUNCATE TABLE
  • SHUTDOWN
  • UNINSTALL {PLUGIN | SONAME}
  • UPDATE

Синонимы здесь не перечислены, но могут быть использованы. Например, DESC можно использовать вместо DESCRIBE.

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

Обратите внимание, что если запрос можно выполнить в хранимой процедуре, он будет работать, даже если вызывается подготовленным запросом. Например, SIGNAL нельзя непосредственно подготовить. Однако он разрешен в хранимых процедурах. Если процедура x() содержит SIGNAL, вы по-прежнему можете подготовить и выполнить подготовленный запрос «CALL x();».

PREPARE поддерживает большинство типов выражений, например:

PREPARE stmt FROM CONCAT('SELECT * FROM ', table_name);

Если PREPARE используется с неподдерживаемым заявлением, генерируется следующая ошибка:

ERROR 1295 (HY000): This command is not supported in the prepared statement protocol yet

Пример

create table t1 (a int,b char(10));
insert into t1 values (1,"one"),(2, "two"),(3,"three");
prepare test from "select * from t1 where a=?";
set @param=2;
execute test using @param;
+------+------+
| a    | b    |
+------+------+
|    2 | two  |
+------+------+
set @param=3;
execute test using @param;
+------+-------+
| a    | b     |
+------+-------+
|    3 | three |
+------+-------+
deallocate prepare test;

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

CREATE PROCEDURE test.stmt_test(IN tab_name VARCHAR(64))
BEGIN
	SET @sql = CONCAT('SELECT COUNT(*) FROM ', tab_name);
	PREPARE stmt FROM @sql;
	EXECUTE stmt;
	DEALLOCATE PREPARE stmt;
END;

CALL test.stmt_test('mysql.user');
+----------+
| COUNT(*) |
+----------+
|        4 |
+----------+

Использование переменных в подготовленных запросах:

PREPARE stmt FROM 'SELECT @x;';

SET @x = 1;

EXECUTE stmt;
+------+
| @x   |
+------+
|    1 |
+------+

SET @x = 0;

EXECUTE stmt;
+------+
| @x   |
+------+
|    0 |
+------+

DEALLOCATE PREPARE stmt;

См. также

  • Параметры вывода в PREPARE
  • Заявление EXECUTE
  • DEALLOCATE/DROP Подготовленного запроса
  • EXECUTE IMMEDIATE
  • Режим Oracle от MariaDB 10.3
Содержимое, воспроизведённое на этом сайте, является собственностью соответствующих владельцев, и это содержимое не проверяется заранее MariaDB. Мнения, информация и мнения, выраженные в этом содержании, не обязательно отражают взгляды MariaDB или любой другой стороны.

© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/prepare-statement/

Spec-Zone.ru

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