MySQL 8.0 C API 开发者指南  / 第 5 章 C API 基本接口  /  5.1 C API 基本接口概述

5.1 C API 基本接口概述

应用程序应该使用这个大纲来通过客户端库与 MySQL 交互:

  1. 通过调用初始化 MySQL 客户端库 mysql_library_init()。此函数存在于libmysqlclient C 客户端库和libmysqld嵌入式服务器库中,因此无论您是通过与标志链接来构建常规客户端程序 -libmysqlclient,还是通过与标志链接来构建嵌入式服务器应用程序,都会使用它-libmysqld

  2. 通过调用初始化连接处理程序 mysql_init()并通过调用连接到服务器 mysql_real_connect()

  3. 发出 SQL 语句并处理其结果。(以下讨论提供了有关如何执行此操作的更多信息。)

  4. 通过调用 关闭与 MySQL 服务器的连接 mysql_close()

  5. 通过调用结束使用 MySQL 客户端库 mysql_library_end()

调用 mysql_library_init()和 的目的mysql_library_end()是提供 MySQL 客户端库的正确初始化和完成。对于与客户端库链接的应用程序,它们提供改进的内存管理。如果您不调用 mysql_library_end(),则会保留一块内存。(这不会增加应用程序使用的内存量,但一些内存泄漏检测器会抱怨它。)对于与嵌入式服务器链接的应用程序,这些调用会启动和停止服务器。

在非多线程环境中, mysql_library_init()可以省略对 的调用,因为mysql_init()必要时会自动调用它。但是, mysql_library_init()在多线程环境中不是线程安全的,因此 mysql_init()调用 mysql_library_init(). 您必须mysql_library_init() 在生成任何线程之前调用,或者使用互斥锁来保护调用,无论您是调用 mysql_library_init()还是间接通过mysql_init(). 这应该在任何其他客户端库调用之前完成。

要连接到服务器,调用 mysql_init()以初始化连接处理程序,然后调用 mysql_real_connect()该处理程序(连同主机名、用户名和密码等其他信息)。完成连接后,调用 mysql_close()以终止它。不要在处理程序关闭后使用它。

连接后, mysql_real_connect()reconnect标志( MYSQL结构的一部分)设置为值 0。您可以使用该 MYSQL_OPT_RECONNECT选项 mysql_options()来控制重新连接行为。1 如果由于连接丢失而无法执行语句,则 设置标志使客户端在放弃之前尝试重新连接到服务器。

当连接处于活动状态时,客户端可以使用 mysql_real_query()或 向服务器发送 SQL 语句mysql_query()。两者之间的区别在于, mysql_query()期望查询被指定为以空字符结尾的字符串,而 mysql_real_query()期望查询被计数的字符串。如果字符串包含二进制数据(可能包含空字节),则必须使用 mysql_real_query().

对于每个非SELECT查询(例如 , , INSERT) ,您可以通过调用 找出更改(影响)的行数 。 UPDATEDELETEmysql_affected_rows()

对于SELECT查询,您检索选定的行作为结果集。(请注意,有些语句是 SELECT-like 的,因为它们返回行。这些包括SHOWDESCRIBEEXPLAIN。将这些语句与语句一样对待SELECT。)

客户端有两种方式处理结果集。一种方法是通过调用 一次性检索整个结果集 mysql_store_result()。此函数从服务器获取查询返回的所有行,并将它们存储在客户端中。第二种方式是客户端通过调用 mysql_use_result(). 此函数初始化检索,但实际上并未从服务器获取任何行。

在这两种情况下,您都可以通过调用访问行 mysql_fetch_row()。使用 mysql_store_result(), mysql_fetch_row()访问之前从服务器获取的行。使用 mysql_use_result()mysql_fetch_row()实际上是从服务器检索行。有关每行数据大小的信息可通过调用 获得 mysql_fetch_lengths()

完成结果集后,调用 mysql_free_result()以释放用于它的内存。

这两种检索机制是互补的。选择最适合每个客户端应用程序的方法。在实践中,客户倾向于 mysql_store_result()更普遍地使用。

的一个优点 是,因为行已全部提取到客户端,您不仅可以按顺序访问行,还可以使用 ormysql_store_result()在结果集中来回移动以更改结果集中的当前行位置。您还可以通过调用 来找出有多少行 。另一方面, 大型结果集的内存要求可能非常高,您更有可能遇到内存不足的情况。 mysql_data_seek()mysql_row_seek()mysql_num_rows()mysql_store_result()

的一个优点mysql_use_result() 是客户端对结果集需要更少的内存,因为它一次只维护一行(并且因为分配开销更少, mysql_use_result()所以可以更快)。缺点是你必须快速处理每一行以避免占用服务器,你不能随机访问结果集中的行(你只能顺序访问行),并且结果集中的行数是未知的,直到你已经全部找回了。此外,您必须 检索所有行,即使您在检索过程中确定您已经找到了要查找的信息。

API 使客户端可以在不知道语句是否为SELECT. mysql_store_result()您可以通过在每个 mysql_real_query()(or mysql_query())之后调用来做到这一点 。如果结果集调用成功,则语句为 a SELECT,您可以读取行。如果结果集调用失败,则调用 mysql_field_count()以确定结果是否确实是预期的。如果 mysql_field_count()返回零,则该语句不返回任何数据(表明它是 INSERTUPDATEDELETE等等),并且不应返回行。如果 mysql_field_count()非零,语句应该返回行,但没有。这表明该语句 SELECT失败了。mysql_field_count()有关如何完成此操作的示例, 请参阅说明 。

两者都mysql_store_result()使 mysql_use_result()您能够获得有关构成结果集的字段的信息(字段的数量、它们的名称和类型等)。mysql_fetch_field() 您可以通过重复 调用按顺序访问行内的字段信息,或通过调用按行内的字段号访问字段信息mysql_fetch_field_direct()。当前字段光标位置可以通过调用 来改变 mysql_field_seek()。设置字段游标会影响对 的后续调用 mysql_fetch_field()。您还可以通过调用 一次性获取所有字段的信息 mysql_fetch_fields()

为了检测和报告错误,MySQL 通过 mysql_errno()mysql_error()函数提供对错误信息的访问。这些函数返回最近调用的可能成功或失败的函数的错误代码或错误消息,使您能够确定错误发生的时间和原因。