MySQL 8.0提供了对服务器端准备语句的支持。这种支持利用了高效的客户机/服务器二进制协议。使用准备好的语句和占位符的参数值有以下好处:
以下各节概述了预置语句的特点:
应用程序中的预置语句
可以通过客户机编程接口使用服务器端准备好的语句,包括MySQL C API客户端库对于C程序,MySQL连接器/ J对于Java程序,以及MySQL连接器/净使用。net技术的程序。例如,C API提供了一组函数调用,这些调用构成了它的准备语句API。看到C API准备语句接口.通过链接C客户端库,其他语言接口可以为使用二进制协议的预置语句提供支持,例如mysqli
扩展, PHP 5.0及更高版本中可用。
SQL脚本中的预处理语句
可以使用预备语句的另一种SQL接口。这个接口没有通过准备好的语句API使用二进制协议那么有效,但不需要编程,因为它直接在SQL级可用:
当没有可用的编程接口时,您可以使用它。
您可以从任何可以将SQL语句发送到服务器执行的程序中使用它,例如mysql客户端程序。
即使客户端使用的是旧版本的客户端库,您也可以使用它。
准备语句的SQL语法旨在用于以下情况:
在编写应用程序之前,测试预处理语句在应用程序中的工作方式。
在无法访问支持预处理语句的编程API时,使用预处理语句。
使用预置语句交互式地排除应用程序问题。
创建一个用准备好的语句重现问题的测试用例,以便您可以提交错误报告。
准备,执行和释放准备语句
准备语句的SQL语法基于以下三种SQL语句:
准备
为执行准备一个语句(参见第13.5.1节,“准备声明”).执行
执行预处理语句(请参见第13.5.2节," EXECUTE语句").释放准备
释放一个准备好的语句(参见第13.5.3节," DEALLOCATE PREPARE语句").
下面的例子展示了两种等价的方法来准备一个命题,即给定两个边的长度来计算三角形的斜边。
第一个例子展示了如何通过使用字符串字面量来提供语句的文本来创建一个预处理语句:
SELECT SQRT(POW(?,2) + POW(?,2)) AS斜边';mysql> SET @a = 3;mysql> SET @b = 4;mysql> EXECUTE stmt1 USING+------------+ | 斜边 | +------------+ | 5 | +------------+ mysql >释放准备stmt1;
第二个例子类似,但将语句的文本作为用户变量提供:
mysql> SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS斜边';mysql>准备stmt2mysql> SET @a = 6;mysql> SET @b = 8;mysql> EXECUTE stmt2 USING+------------+ | 斜边 | +------------+ | 10 | +------------+ mysql >释放准备stmt2;
下面是一个额外的例子,演示了如何通过将表的名称存储为一个用户变量来选择在运行时执行查询的表:
mysql >使用测试;创建表t1 (INT NOT NULL)INSERT INTO t1 VALUES (4), (8), (11), (32), (80);mysql> SET @table = 't1'mysql> SET @s = CONCAT('SELECT * FROM ', @table);mysql>准备stmt3mysql >执行stmt3;+——+ | | +----+ | 32 11 8 4 | | | | | | | | 80年 | +----+ mysql >释放准备stmt3;
准备好的语句特定于创建它的会话。如果终止会话而不释放之前准备好的语句,服务器将自动释放它。
准备好的语句对会话也是全局的。如果在存储例程中创建了预处理语句,则在存储例程结束时不会释放该语句。
要防止同时创建太多预处理语句,请设置max_prepared_stmt_count
系统变量。为了防止使用预处理语句,请将该值设置为0。
预处理语句中允许的SQL语法
以下SQL语句可以作为准备语句使用:
ALTER TABLE改变用户分析表缓存索引调用修改主校验和{表|表}{创建|删除}指数提交{创建|重命名|删除}{创建|删除}数据库用户表{创建|重命名|删除}{创建|删除}视图删除做冲洗{表|表| | | |主机权限日志表与读锁状态| | | |奴隶主人USER_RESOURCES}格兰特插入安装插件杀死指数加载到缓存优化表重命名表修理表取代重置{主|从}取消选择Set 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
不支持其他语句。
为了符合SQL标准,诊断语句是不可准备的,MySQL不支持以下准备语句:
显示警告
,显示COUNT(*)警告
显示错误
,显示COUNT(*)错误
语句,该语句包含对
warning_count
或error_count
系统变量。
一般来说,SQL准备语句中不允许的语句在存储程序中也是不允许的。例外情况载于第25.8节,“存储程序的限制”.
对预处理语句引用的表或视图的元数据更改将被检测到,并导致在下一次执行语句时自动重新准备语句。有关更多信息,请参见第8.10.3节,“预处理语句和存储程序的缓存”.
的参数可以使用占位符限制
子句。看到第13.2.10节,“SELECT语句”.
在准备调用
语句的使用准备
而且执行
,占位符支持出
而且INOUT
参数从MySQL 8.0开始提供。看到第13.2.1节,“CALL语句”,这是早期版本的一个示例和解决方案。占位符可用于在
参数与版本无关。
不能以嵌套方式使用预处理语句的SQL语法。也就是说,传递给的语句准备
本身不可能是准备
,执行
,或释放准备
声明。
预处理语句的SQL语法不同于使用预处理语句API调用。例如,您不能使用mysql_stmt_prepare ()
用C语言编写的API函数准备
,执行
,或释放准备
声明。
预处理语句的SQL语法可以在存储过程中使用,但不能在存储函数或触发器中使用。但是,游标不能用于准备和执行时使用的动态语句准备
而且执行
.游标的语句在创建游标时被检查,因此该语句不能是动态的。
预处理语句的SQL语法不支持多语句(即在一个字符串中由;
字符)。
编写C程序,使用调用
SQL语句来执行包含预处理语句的存储过程CLIENT_MULTI_RESULTS
标志必须启用。这是因为调用
除了过程中执行的语句可能返回的任何结果集之外,还返回一个结果来指示调用状态。
CLIENT_MULTI_RESULTS
呼叫时是否可以启用mysql_real_connect ()
,可以通过传递CLIENT_MULTI_RESULTS
标记自身,或通过传递隐式地标记CLIENT_MULTI_STATEMENTS
(也可以CLIENT_MULTI_RESULTS
).有关更多信息,请参见第13.2.1节,“CALL语句”.