27.7.9 C API 准备语句功能概述

下 table 总结了可用于预处理语句处理的功能。有关更多详细信息,请参见第 27.7.10 节“ C API 准备的语句功能描述”中的描述。

调用mysql_stmt_init()创建语句处理程序,然后调用mysql_stmt_prepare()准备语句字符串,mysql_stmt_bind_param()提供参数数据,并mysql_stmt_execute()执行语句。您可以通过更改mysql_stmt_bind_param()提供的各个缓冲区中的参数值来重复mysql_stmt_execute()

您可以使用mysql_stmt_send_long_data()向服务器发送文本或二进制数据。参见第 27.7.10.26 节,“ mysql_stmt_send_long_data()”

如果该语句是SELECT或生成结果集的任何其他语句,则mysql_stmt_prepare()还以MYSQL_RES结果集到mysql_stmt_result_metadata()的形式返回结果集元数据信息。

您可以使用mysql_stmt_bind_result()提供结果缓冲区,以便mysql_stmt_fetch()自动将数据返回到这些缓冲区。这是逐行读取。

语句执行完成后,使用mysql_stmt_close()关闭语句处理程序,以便可以释放与其关联的所有资源。届时,处理程序将变为无效,不应再使用。

如果您通过调用mysql_stmt_result_metadata()获得了SELECT语句的结果集元数据,则还应该使用mysql_free_result()释放元数据。

Execution Steps

为了准备和执行一条语句,应用程序遵循以下步骤:

  • 使用mysql_stmt_init()创建一个准备好的语句处理程序。要在服务器上准备该语句,请调用mysql_stmt_prepare()并将其传递给包含 SQL 语句的字符串。

  • 如果该语句将产生结果集,请调用mysql_stmt_result_metadata()以获取结果集元数据。这种元数据本身就是结果集的形式,尽管它与包含查询返回的行的元数据是分开的。元数据结果集指示结果中有多少列,并包含有关每列的信息。

  • 使用mysql_stmt_bind_param()设置任何参数的值。必须设置所有参数。否则,语句执行将返回错误或产生意外结果。

  • 调用mysql_stmt_execute()执行该语句。

  • 如果该语句产生结果集,请通过调用mysql_stmt_bind_result()绑定数据缓冲区以用于检索行值。

  • 通过重复调用mysql_stmt_fetch()逐行将数据提取到缓冲区中,直到找不到更多行。

  • 通过更改参数值并重新执行该语句,根据需要重复步骤 3 到 6.

调用mysql_stmt_prepare()时,MySQLClient 端/服务器协议执行以下操作:

  • 服务器解析该语句,然后通过分配一条语句 ID 将正常状态发送回 Client 端。如果它是面向结果集的语句,它还会发送参数总数,列数及其元数据。服务器在此调用期间检查语句的所有语法和语义。

  • Client 端使用此语句 ID 进行进一步的操作,以便服务器可以从其语句池中识别该语句。

调用mysql_stmt_execute()时,MySQLClient 端/服务器协议执行以下操作:

  • Client 端使用语句处理程序,并将参数数据发送到服务器。

  • 服务器使用 Client 端提供的 ID 识别语句,用新提供的数据替换参数标记,然后执行语句。如果该语句产生结果集,则服务器将数据发送回 Client 端。否则,它将发送正常状态,并且更改,删除或插入的行数。

调用mysql_stmt_fetch()时,MySQLClient 端/服务器协议执行以下操作:

  • Client 端从结果集的当前行读取数据,并通过进行必要的转换将其放入应用程序数据缓冲区。如果应用程序缓冲区类型与服务器返回的字段类型相同,则转换很简单。

如果发生错误,则可以分别使用mysql_stmt_errno()mysql_stmt_error()mysql_stmt_sqlstate()来获取语句错误号,错误消息和 SQLSTATE 代码。

准备语句记录

对于使用mysql_stmt_prepare()mysql_stmt_execute() C API 函数执行的准备好的语句,服务器将PrepareExecute行写入常规查询日志,以便您可以知道何时准备和执行语句。

假设您准备并执行如下语句:

由于上述调用,服务器将以下行写入常规查询日志:

Prepare  [1] SELECT ?
Execute  [1] SELECT 3

日志中的每个PrepareExecute行都标记有[N]语句标识符,以便您可以跟踪记录了哪个准备好的语句。 * N 是一个正整数。如果有多个同时为 Client 激活的准备好的语句,则 N *可能大于 1.每条Execute行显示了将数据值替换为?参数后的准备好的语句。