使用PREPARE将语句用占位符(?)(作为参数标记)拼接;使用EXECUTE执行
对参数值使用带占位符,具有以下好处:
- 每次执行语句时解析语句的开销都较小。通常,数据库应用程序处理大量几乎相同的语句,仅对子句中的文字或变量值进行更改,例如WHERE查询和删除,SET更新和VALUES插入。
- 防止SQL注入攻击。参数值可以包含未转义的SQL引号和定界符。
语法:
PREPARE语句准备一个SQL语句,并为其分配一个名称stmt_name,以便以后引用该语句
PREPARE stmt_name FROM preparable_stmt
EXECUTE执行准备好的语句
EXECUTE stmt_name [USING @var_name [, @var_name] ...]
- 如果prepared语句包含任何参数标记,则必须提供一个USING 子句,该子句列出包含要绑定到参数的值的用户变量。参数值只能由用户变量提供,并且USING子句的命名变量必须与语句中参数标记的数量一样多。
- 您可以多次执行给定的预处理语句,将不同的变量传递给它,或者在每次执行之前将变量设置为不同的值
- 预处理语句中无法动态拼接表名与字段名,如果拼接要使用concat()拼接sql
取消分配使用PREPARE生成的准备好的语句stmt_name
{DEALLOCATE | DROP} PREPARE stmt_name
-
取消分配后尝试执行准备好的语句会导致错误。
-
如果创建了太多准备好的语句,并且DEALLOCATE PREPARE语句或会话结束时未将其释放,则可能会遇到max_prepared_stmt_count系统变量强制执行的上限。
示例:
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 |
+------------+
| 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;
预处理允许的语句:
ALTER TABLE
ALTER USER
ANALYZE TABLE
CACHE INDEX
CALL
CHANGE MASTER
CHECKSUM {TABLE | TABLES}
COMMIT
{CREATE | DROP} INDEX
{CREATE | RENAME | DROP} DATABASE
{CREATE | DROP} TABLE
{CREATE | RENAME | DROP} USER
{CREATE | DROP} VIEW
DELETE
DO
FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES
| LOGS | STATUS | MASTER | SLAVE | DES_KEY_FILE | USER_RESOURCES}
GRANT
INSERT
INSTALL PLUGIN
KILL
LOAD INDEX INTO CACHE
OPTIMIZE TABLE
RENAME TABLE
REPAIR TABLE
REPLACE
RESET {MASTER | SLAVE | QUERY CACHE}
REVOKE
SELECT
SET
SHOW {WARNINGS | ERRORS}
SHOW BINLOG EVENTS
SHOW CREATE {PROCEDURE | FUNCTION | EVENT | TABLE | VIEW}
SHOW {MASTER | BINARY} LOGS
SHOW {MASTER | SLAVE} STATUS
SLAVE {START | STOP}
TRUNCATE TABLE
UNINSTALL PLUGIN
UPDATE