EXECUTE IMMEDIATE
EXECUTE IMMEDIATE был введён в MariaDB 10.2.3.
Синтаксис
EXECUTE IMMEDIATE statement
Описание
EXECUTE IMMEDIATE выполняет динамическое SQL-утверждение, созданное на лету, что может уменьшить накладные расходы на производительность.
Например:
EXECUTE IMMEDIATE 'SELECT 1'
что является сокращением для:
prepare stmt from "select 1"; execute stmt; deallocate prepare stmt;
EXECUTE IMMEDIATE поддерживает сложные выражения в качестве источника подготовки и параметров:
EXECUTE IMMEDIATE CONCAT('SELECT COUNT(*) FROM ', 't1', ' WHERE a=?') USING 5+5;
Ограничения: подзапросы и вызовы хранимых функций не поддерживаются в качестве источника подготовки.
Следующие примеры возвращают ошибку:
CREATE OR REPLACE FUNCTION f1() RETURNS VARCHAR(64) RETURN 'SELECT * FROM t1'; EXECUTE IMMEDIATE f1(); ERROR 1970 (42000): EXECUTE IMMEDIATE does not support subqueries or stored functions EXECUTE IMMEDIATE (SELECT 'SELECT * FROM t1'); ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SELECT 'SELECT * FROM t1')' at line 1 CREATE OR REPLACE FUNCTION f1() RETURNS INT RETURN 10; EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING f1(); ERROR 1970 (42000): EXECUTE..USING does not support subqueries or stored functions EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING (SELECT 10); ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SELECT 10)' at line 1
Можно использовать переменные пользователя или SP в качестве обходного решения:
CREATE OR REPLACE FUNCTION f1() RETURNS VARCHAR(64) RETURN 'SELECT * FROM t1'; SET @stmt=f1(); EXECUTE IMMEDIATE @stmt; SET @stmt=(SELECT 'SELECT 1'); EXECUTE IMMEDIATE @stmt; CREATE OR REPLACE FUNCTION f1() RETURNS INT RETURN 10; SET @param=f1(); EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING @param; SET @param=(SELECT 10); EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING @param;
EXECUTE IMMEDIATE поддерживает переменные пользователя и SP переменные как выходные параметры
DELIMITER $$ CREATE OR REPLACE PROCEDURE p1(OUT a INT) BEGIN SET a:= 10; END; $$ DELIMITER ; SET @a=2; EXECUTE IMMEDIATE 'CALL p1(?)' USING @a; SELECT @a; +------+ | @a | +------+ | 10 | +------+
Аналогично PREPARE, EXECUTE IMMEDIATE разрешён в хранимых процедурах, но не разрешён в хранимых функциях.
В этом примере используется EXECUTE IMMEDIATE внутри хранимой процедуры:
DELIMITER $$ CREATE OR REPLACE PROCEDURE p1() BEGIN EXECUTE IMMEDIATE 'SELECT 1'; END; $$ DELIMITER ; CALL p1; +---+ | 1 | +---+ | 1 | +---+
Этот скрипт возвращает ошибку:
DELIMITER $$ CREATE FUNCTION f1() RETURNS INT BEGIN EXECUTE IMMEDIATE 'DO 1'; RETURN 1; END; $$ ERROR 1336 (0A000): Dynamic SQL is not allowed in stored function or trigger
EXECUTE IMMEDIATE может использовать индикаторы DEFAULT и IGNORE в качестве параметров связывания:
CREATE OR REPLACE TABLE t1 (a INT DEFAULT 10); EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?)' USING DEFAULT; SELECT * FROM t1; +------+ | a | +------+ | 10 | +------+
EXECUTE IMMEDIATE увеличивает переменную статуса Com_execute_immediate, а также переменные статуса Com_stmt_prepare, Com_stmt_execute и Com_stmt_close.
Обратите внимание, что EXECUTE IMMEDIATE не увеличивает переменную статуса Com_execute_sql. Com_execute_sql используется только для PREPARE..EXECUTE.
Этот снимок экрана сеанса демонстрирует, как EXECUTE IMMEDIATE влияет на переменные статуса:
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME RLIKE
('COM_(EXECUTE|STMT_PREPARE|STMT_EXECUTE|STMT_CLOSE)');
+-----------------------+----------------+
| VARIABLE_NAME | VARIABLE_VALUE |
+-----------------------+----------------+
| COM_EXECUTE_IMMEDIATE | 0 |
| COM_EXECUTE_SQL | 0 |
| COM_STMT_CLOSE | 0 |
| COM_STMT_EXECUTE | 0 |
| COM_STMT_PREPARE | 0 |
+-----------------------+----------------+
EXECUTE IMMEDIATE 'SELECT 1';
+---+
| 1 |
+---+
| 1 |
+---+
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME RLIKE
('COM_(EXECUTE|STMT_PREPARE|STMT_EXECUTE|STMT_CLOSE)');
+-----------------------+----------------+
| VARIABLE_NAME | VARIABLE_VALUE |
+-----------------------+----------------+
| COM_EXECUTE_IMMEDIATE | 1 |
| COM_EXECUTE_SQL | 0 |
| COM_STMT_CLOSE | 1 |
| COM_STMT_EXECUTE | 1 |
| COM_STMT_PREPARE | 1 |
+-----------------------+----------------+
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/execute-immediate/