MySQL 8.0 provides support for server-side prepared statements. MySQL 8.0提供了对服务器端准备语句的支持。This support takes advantage of the efficient client/server binary protocol. 这种支持利用了高效的客户机/服务器二进制协议。Using prepared statements with placeholders for parameter values has the following benefits:为参数值使用带有占位符的准备语句有以下好处:
Less overhead for parsing the statement each time it is executed. 减少每次执行语句时解析语句的开销。Typically, database applications process large volumes of almost-identical statements, with only changes to literal or variable values in clauses such as 通常,数据库应用程序处理大量几乎相同的语句,只更改子句中的文字值或变量值,例如查询和删除的WHERE
for queries and deletes, SET
for updates, and VALUES
for inserts.WHERE
、更新的SET
和插入的VALUES
。
Protection against SQL injection attacks. 防止SQL注入攻击。The parameter values can contain unescaped SQL quote and delimiter characters.参数值可以包含未转义的SQL引号和分隔符字符。
The following sections provide an overview of the characteristics of prepared statements:以下各节概述了已编制报表的特点:
You can use server-side prepared statements through client programming interfaces, including the MySQL C API client library for C programs, MySQL Connector/J for Java programs, and MySQL Connector/NET for programs using .NET technologies. 您可以通过客户端编程接口使用服务器端准备的语句,包括用于C程序的MySQL C API客户端库、用于Java程序的MySQL Connector/J以及用于使用.NET技术的程序的MySQL Connector/NET。For example, the C API provides a set of function calls that make up its prepared statement API. 例如,C API提供了一组函数调用,这些函数调用构成了其准备好的语句API。See C API Prepared Statement Interface. 参见C API编写的语句接口。Other language interfaces can provide support for prepared statements that use the binary protocol by linking in the C client library, one example being the 其他语言接口可以通过在C客户机库中链接,为使用二进制协议的准备好的语句提供支持,其中一个例子是在PHP5.0及更高版本中提供的mysqli
extension, available in PHP 5.0 and higher.mysqli
扩展。
An alternative SQL interface to prepared statements is available. 准备语句的另一个SQL接口是可用的。This interface is not as efficient as using the binary protocol through a prepared statement API, but requires no programming because it is available directly at the SQL level:此接口的效率不如通过预处理语句API使用二进制协议,但不需要编程,因为它直接在SQL级别可用:
You can use it when no programming interface is available to you.当没有可用的编程接口时,可以使用它。
You can use it from any program that can send SQL statements to the server to be executed, such as the mysql client program.您可以从任何可以向服务器发送SQL语句以执行的程序(例如mysql客户机程序)中使用它。
You can use it even if the client is using an old version of the client library.即使客户端使用的是旧版本的客户端库,也可以使用它。
SQL syntax for prepared statements is intended to be used for situations such as these:准备语句的SQL语法用于以下情况:
To test how prepared statements work in your application before coding it.在编写应用程序之前测试准备好的语句在应用程序中的工作方式。
To use prepared statements when you do not have access to a programming API that supports them.在无法访问支持准备语句的编程API时使用准备语句。
To interactively troubleshoot application issues with prepared statements.使用准备好的语句交互式地解决应用程序问题。
To create a test case that reproduces a problem with prepared statements, so that you can file a bug report.创建一个用准备好的语句再现问题的测试用例,以便您可以提交一个bug报告。
SQL syntax for prepared statements is based on three SQL statements:准备语句的SQL语法基于以下三种SQL语句:
PREPARE
prepares a statement for execution (see Section 13.5.1, “PREPARE Statement”).PREPARE
准备了一个要执行的语句(请参阅第13.5.1节,“PREPARE语句”)。
EXECUTE
executes a prepared statement (see Section 13.5.2, “EXECUTE Statement”).EXECUTE
执行准备好的语句(请参阅第13.5.2节,“EXECUTE语句”)。
DEALLOCATE PREPARE
releases a prepared statement (see Section 13.5.3, “DEALLOCATE PREPARE Statement”).DEALLOCATE PREPARE
发布已准备好的语句(请参阅第13.5.3节,“DEALLOCATE PREPARE语句”)。
The following examples show two equivalent ways of preparing a statement that computes the hypotenuse of a triangle given the lengths of the two sides.下面的示例展示了两种编写语句的等效方法,该语句在给定三角形两边长度的情况下计算三角形的斜边。
The first example shows how to create a prepared statement by using a string literal to supply the text of the statement:第一个示例演示如何通过使用字符串文本提供语句的文本来创建准备好的语句:
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;
The second example is similar, but supplies the text of the statement as a user variable:第二个示例类似,但将语句的文本作为用户变量提供:
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;
Here is an additional example that demonstrates how to choose the table on which to perform a query at runtime, by storing the name of the table as a user variable:下面是一个附加示例,演示如何通过将表的名称存储为用户变量来选择在运行时执行查询的表:
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;
A prepared statement is specific to the session in which it was created. 准备好的语句特定于创建它的会话。If you terminate a session without deallocating a previously prepared statement, the server deallocates it automatically.如果终止会话而不释放先前准备的语句,则服务器会自动释放该语句。
A prepared statement is also global to the session. 事先准备好的发言也是本届会议的核心内容。If you create a prepared statement within a stored routine, it is not deallocated when the stored routine ends.如果在存储例程中创建准备语句,则在存储例程结束时不会释放该语句。
To guard against too many prepared statements being created simultaneously, set the 要防止同时创建过多的准备语句,请设置max_prepared_stmt_count
system variable. max_prepared_stmt_count
系统变量。To prevent the use of prepared statements, set the value to 0.若要防止使用准备好的语句,请将该值设置为0。
The following SQL statements can be used as prepared statements:以下SQL语句可用作准备语句:
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 | USER_RESOURCES} GRANT INSERT INSTALL PLUGIN KILL LOAD INDEX INTO CACHE OPTIMIZE TABLE RENAME TABLE REPAIR TABLE REPLACE RESET {MASTER | SLAVE} REVOKE SELECT 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
Other statements are not supported.不支持其他语句。
For compliance with the SQL standard, which states that diagnostics statements are not preparable, MySQL does not support the following as prepared statements:为了符合SQL标准,即诊断语句是不可准备的,MySQL不支持以下已准备语句:
SHOW WARNINGS
, SHOW COUNT(*) WARNINGS
SHOW ERRORS
, SHOW COUNT(*) ERRORS
Statements containing any reference to the 包含对warning_count
or error_count
system variable.warning_count
或error_count
系统变量的任何引用的语句。
Generally, statements not permitted in SQL prepared statements are also not permitted in stored programs. 一般来说,SQL准备语句中不允许的语句在存储程序中也不允许。Exceptions are noted in Section 25.8, “Restrictions on Stored Programs”.例外情况请参阅第25.8节,“存储程序的限制”。
Metadata changes to tables or views referred to by prepared statements are detected and cause automatic repreparation of the statement when it is next executed. 检测到对已准备语句引用的表或视图的元数据更改,并在下次执行语句时自动重新准备语句。For more information, see Section 8.10.3, “Caching of Prepared Statements and Stored Programs”.有关更多信息,请参阅第8.10.3节,“准备语句和存储程序的缓存”。
Placeholders can be used for the arguments of the 当使用准备好的语句时,占位符可用于LIMIT
clause when using prepared statements. LIMIT
子句的参数。See Section 13.2.10, “SELECT Statement”.请参阅第13.2.10节,“SELECT语句”。
In prepared 在与CALL
statements used with PREPARE
and EXECUTE
, placeholder support for OUT
and INOUT
parameters is available beginning with MySQL 8.0. PREPARE
和EXECUTE
一起使用的准备好的CALL
语句中,从MySQL 8.0开始,可以使用对OUT
和INOUT
参数的占位符支持。See Section 13.2.1, “CALL Statement”, for an example and a workaround for earlier versions. 有关早期版本的示例和解决方法,请参阅第13.2.1节,“CALL语句”。Placeholders can be used for 占位符可用于IN
parameters regardless of version.IN
参数,无论版本如何。
SQL syntax for prepared statements cannot be used in nested fashion. 准备语句的SQL语法不能以嵌套方式使用。That is, a statement passed to 也就是说,传递给PREPARE
cannot itself be a PREPARE
, EXECUTE
, or DEALLOCATE PREPARE
statement.PREPARE
的语句本身不能是PREPARE
、EXECUTE
或DEALLOCATE PREPARE
语句。
SQL syntax for prepared statements is distinct from using prepared statement API calls. 预处理语句的SQL语法不同于使用预处理语句API调用。For example, you cannot use the 例如,您不能使用mysql_stmt_prepare()
C API function to prepare a PREPARE
, EXECUTE
, or DEALLOCATE PREPARE
statement.mysql_stmt_prepare()
C API函数来准备PREPARE
、EXECUTE
或DEALLOCATE PREPARE
语句。
SQL syntax for prepared statements can be used within stored procedures, but not in stored functions or triggers. 预处理语句的SQL语法可以在存储过程中使用,但不能在存储函数或触发器中使用。However, a cursor cannot be used for a dynamic statement that is prepared and executed with 但是,游标不能用于使用PREPARE
and EXECUTE
. PREPARE
和EXECUTE
准备和执行的动态语句。The statement for a cursor is checked at cursor creation time, so the statement cannot be dynamic.游标的语句是在游标创建时检查的,因此该语句不能是动态的。
SQL syntax for prepared statements does not support multi-statements (that is, multiple statements within a single string separated by 准备语句的SQL语法不支持多语句(即,单个字符串中的多个语句用分隔符;
characters).;
字符分隔)。
To write C programs that use the 要编写使用CALL
SQL statement to execute stored procedures that contain prepared statements, the CLIENT_MULTI_RESULTS
flag must be enabled. CALL
SQL语句执行包含准备语句的存储过程的C程序,必须启用CLIENT_MULTI_RESULTS
标志。This is because each 这是因为除了过程中执行的语句可能返回的任何结果集之外,每个CALL
returns a result to indicate the call status, in addition to any result sets that might be returned by statements executed within the procedure.CALL
还返回一个结果来指示调用状态。
调用CLIENT_MULTI_RESULTS
can be enabled when you call mysql_real_connect()
, either explicitly by passing the CLIENT_MULTI_RESULTS
flag itself, or implicitly by passing CLIENT_MULTI_STATEMENTS
(which also enables CLIENT_MULTI_RESULTS
). mysql_real_connect()
时,可以显式地通过传递CLIENT_MULTI_RESULTS
标志本身来启用CLIENT_MULTI_RESULTS
,也可以隐式地通过传递CLIENT_MULTI_STATEMENTS
(这也可以启用CLIENT_MULTI_RESULTS
)。For additional information, see Section 13.2.1, “CALL Statement”.有关更多信息,请参阅第13.2.1节,“CALL语句”。