跳到主要内容
MySQL 在 C/C++ 中的使用 | 极客日志
C++
MySQL 在 C/C++ 中的使用 综述由AI生成 在 C/C++ 中使用 MySQL 数据库的核心 API。内容涵盖初始化连接句柄(mysql_init)、建立连接(mysql_real_connect)、执行 SQL 语句(mysql_query/mysql_real_query)、处理查询结果(mysql_store_result/mysql_use_result)以及错误处理函数(mysql_error/mysql_errno)。此外还详细说明了行数据处理(mysql_fetch_row)、字段信息获取(mysql_fetch_fields)、结果集定位(mysql_data_seek)及其他实用函数(mysql_affected_rows/mysql_insert_id)。通过示例代码展示了如何遍历结果集及安全读取字段数据,适合需要集成 MySQL 功能的 C/C++ 开发者参考。
漫步 发布于 2026/3/30 更新于 2026/5/24 29 浏览1. 初始化与连接函数
(1) mysql_init()
MYSQL *mysql_init (MYSQL *mysql) ;
功能:初始化 MySQL 连接句柄(结构体)。
说明:若参数为 NULL,会自动分配新的句柄,需在最后用 mysql_close() 释放。
需结合 mysql_close() 使用。
功能:关闭 MySQL 连接并释放句柄。
void mysql_close (MYSQL *mysql) ;
(2) mysql_real_connect()
功能:建立与 MySQL 服务器的连接。
MYSQL *mysql_real_connect (
MYSQL *mysql, const char *host, const char *user, const char *passwd,
const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag
) ;
参数说明:
MYSQL *mysql:已初始化的句柄
const char *host:服务器地址("localhost" 或 IP)
const char *user:用户名
const char *passwd:密码
const char *db:数据库名(可为 NULL,后续再选择)
unsigned int port:端口(通常为 3306,0 表示默认)
const char *unix_socket:Unix 套接字(NULL 表示不使用)
unsigned long client_flag:客户端标志(通常为 0)
说明:成功返回连接句柄,失败返回 NULL,可通过 mysql_error() 获取错误信息。
2. 执行 SQL 语句函数
(1) mysql_query()
功能:执行 SQL 语句(字符串形式,不含二进制数据)。
;
int
mysql_query
(MYSQL *mysql, const char *stmt_str)
说明:成功返回 0,失败返回非 0。适合执行 SELECT、INSERT、UPDATE 等常规语句。
(2) mysql_real_query() 功能:执行 SQL 语句(支持包含二进制数据的语句)。
int mysql_real_query (MYSQL *mysql, const char *stmt_str, unsigned long length) ;
说明:与 mysql_query() 类似,但需显式指定语句长度,适合处理含特殊字符的 SQL。
3. 处理查询结果函数
(1) mysql_store_result() 功能:获取 SELECT 等查询的全部结果集(一次性加载到内存)。
MYSQL_RES *mysql_store_result (MYSQL *mysql) ;
说明:成功返回结果集句柄,失败返回 NULL,需用 mysql_free_result() 释放。
(2) mysql_use_result() MYSQL_RES *mysql_use_result (MYSQL *mysql) ;
说明:适合处理大量数据,但需在读取完所有行后才能执行其他语句。
4. 错误处理函数
(1) mysql_error() const char *mysql_error (MYSQL *mysql) ;
(2) mysql_errno() unsigned int mysql_errno (MYSQL *mysql) ;
5. 行数据处理函数 unsigned int mysql_num_fields (MYSQL_RES *result) ;
my_ulonglong mysql_num_rows (MYSQL_RES *result) ;
(1) mysql_fetch_row() 功能:从结果集(MYSQL_RES*)中获取一行数据。
MYSQL_ROW mysql_fetch_row (MYSQL_RES *result) ;
返回值是 MYSQL_ROW 类型(本质是 char**,字符串数组),每个元素对应一列数据
当无更多行或出错时返回 NULL
数据以字符串形式存储(即使是数字类型,也需手动转换)
MYSQL_RES *res = mysql_store_result (mysql);
if (res == nullptr ) {
std::cerr << "mysql_store_result error" << std::endl;
return 4 ;
}
int rows = mysql_num_rows (res);
int fields = mysql_num_fields (res);
std::cout << "行:" << rows << std::endl;
std::cout << "列:" << fields << std::endl;
MYSQL_FIELD *fields_array = mysql_fetch_fields (res);
for (int i = 0 ; i < rows; i++) {
MYSQL_ROW row = mysql_fetch_row (res);
for (int j = 0 ; j < fields; j++) {
std::cout << row[j] << "\t" ;
}
std::cout << "\n" ;
}
虽然外层循环的变量 i 没有直接参与 mysql_fetch_row(res) 的调用,但循环本身起到了控制读取次数的作用,而 mysql_fetch_row 函数内部会维护一个'当前行指针',每次调用都会自动移动到下一行,这就是为什么能按行读取结果的核心原因。
(2) mysql_fetch_lengths() unsigned long *mysql_fetch_lengths (MYSQL_RES *result) ;
需在 mysql_fetch_row() 之后调用,获取当前行的字段长度数组
用于处理二进制数据或包含 \0 的字符串(避免被截断)
MYSQL_ROW row = mysql_fetch_row (result);
unsigned long *lengths = mysql_fetch_lengths (result);
for (int i = 0 ; i < cols; i++) {
printf ("字段 %d: %.*s\n" , i, lengths[i], row[i]);
}
6. 字段(列)信息处理函数
(1) mysql_fetch_field() MYSQL_FIELD *mysql_fetch_field (MYSQL_RES *result) ;
说明:返回 MYSQL_FIELD 结构体指针,包含字段名、类型、长度等信息。多次调用可遍历所有字段,结束时返回 NULL。
MYSQL_FIELD *field;
while ((field = mysql_fetch_field (result))) {
printf ("字段名:%s, 类型:%d, 长度:%lu\n" ,
field->name, field->type, field->length);
}
(2) mysql_fetch_fields() MYSQL_FIELD *mysql_fetch_fields (MYSQL_RES *result) ;
说明:返回字段信息数组的首地址,数组长度为 mysql_num_fields(result)。适合批量获取字段信息,无需循环调用 mysql_fetch_field()。
typedef struct st_mysql_field {
char *name;
char *org_name;
char *table;
char *org_table;
char *db;
char *catalog;
char *def;
unsigned long length;
unsigned long max_length;
unsigned int name_length;
unsigned int org_name_length;
unsigned int table_length;
unsigned int org_table_length;
unsigned int db_length;
unsigned int catalog_length;
unsigned int def_length;
unsigned int flags;
unsigned int decimals;
unsigned int charsetnr;
enum enum_field_types type;
void *extension;
} MYSQL_FIELD;
int cols = mysql_num_fields (result);
MYSQL_FIELD *fields = mysql_fetch_fields (result);
for (int i = 0 ; i < cols; i++) {
printf ("字段 %d: %s\n" , i, fields[i].name);
}
7. 结果集定位与遍历函数
(1) mysql_data_seek() void mysql_data_seek (MYSQL_RES *result, my_ulonglong offset) ;
说明:仅对 mysql_store_result() 获取的结果集有效(全量加载到内存)。offset 为行索引(从 0 开始),需小于 mysql_num_rows(result)。
mysql_data_seek (result, 4 );
MYSQL_ROW row = mysql_fetch_row (result);
(2) mysql_row_seek() 功能:通过行偏移量(MYSQL_ROW_OFFSET)定位行。
MYSQL_ROW_OFFSET mysql_row_seek (MYSQL_RES *result, MYSQL_ROW_OFFSET offset) ;
说明:比 mysql_data_seek() 更底层,偏移量通过 mysql_row_tell() 获取。适用于需要保存 / 恢复行位置的场景。
(3) mysql_row_tell() MYSQL_ROW_OFFSET mysql_row_tell (MYSQL_RES *result) ;
说明:返回当前行的 MYSQL_ROW_OFFSET 类型偏移量,可用于 mysql_row_seek()。
8. 其他实用函数
(1) mysql_affected_rows() 功能:获取上一条 INSERT/UPDATE/DELETE 语句影响的行数。
my_ulonglong mysql_affected_rows (MYSQL *mysql) ;
说明:对于 INSERT,返回插入的行数;对于 UPDATE/DELETE,返回受影响的行数。失败时返回 (my_ulonglong)-1。
(2) mysql_insert_id() 功能:获取上一条 INSERT 语句生成的自增 ID(如主键 AUTO_INCREMENT)。
my_ulonglong mysql_insert_id (MYSQL *mysql) ;
说明:仅对包含自增字段的表有效,且需在 INSERT 执行后立即调用。
这些函数主要用于精细化处理查询结果,包括行数据读取、字段元信息获取、结果集定位等,配合之前提到的核心函数可以完成复杂的数据库操作。
相关免费在线工具 Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
JSON美化和格式化 将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online