MySQL在C/C++中的使用

1.初始化与连接函数

(1)mysql_init()

cpp 复制代码
MYSQL *mysql_init(MYSQL *mysql);

功能:初始化 MySQL 连接句柄(结构体)

说明:若参数为 NULL,会自动分配新的句柄,需在最后用 mysql_close() 释放。

需要结合 **mysql_close()**使用

功能:关闭 MySQL 连接并释放句柄

cpp 复制代码
void mysql_close(MYSQL *mysql);

(2)mysql_real_connect()

功能:建立与 MySQL 服务器的连接

cpp 复制代码
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 语句(字符串形式,不含二进制数据)

cpp 复制代码
int mysql_query(MYSQL *mysql, const char *stmt_str);

说明:成功返回 0,失败返回非 0。适合执行 SELECT、INSERT、UPDATE 等常规语句。

(2)mysql_real_query()

功能:执行 SQL 语句(支持包含二进制数据的语句)

cpp 复制代码
int mysql_real_query( MYSQL *mysql, 
const char *stmt_str, unsigned long length // 语句长度(字节数) );

说明:与 mysql_query() 类似,但需显式指定语句长度,适合处理含特殊字符的 SQL。

3. 处理查询结果函数

(1)mysql_store_result()

功能:获取 SELECT 等查询的全部结果集(一次性加载到内存)

cpp 复制代码
MYSQL_RES *mysql_store_result(MYSQL *mysql); 
说明:成功返回结果集句柄,失败返回 NULL,需用 mysql_free_result() 释放。

(2)mysql_use_result()

功能:获取查询结果集(逐行读取,内存占用低)

cpp 复制代码
MYSQL_RES *mysql_use_result(MYSQL mysql);

说明:适合处理大量数据,但需在读取完所有行后才能执行其他语句。

4. 错误处理函数

(1)mysql_error()

功能:返回最近一次操作的错误信息

cpp 复制代码
const char *mysql_error(MYSQL *mysql);

(2)mysql_errno()

功能:返回最近一次操作的错误代码

cpp 复制代码
unsigned int mysql_errno(MYSQL *mysql);

5. 行数据处理函数

cpp 复制代码
功能:获取结果集的字段数(列数)/ 行数
unsigned int mysql_num_fields(MYSQL_RES *result);  // 列数
my_ulonglong mysql_num_rows(MYSQL_RES *result);    // 行数

(1)mysql_fetch_row

功能:从结果集(MYSQL_RES*)中获取一行数据

cpp 复制代码
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

说明:

  • 返回值是 MYSQL_ROW 类型(本质是 char**,字符串数组),每个元素对应一列数据

  • 当无更多行或出错时返回 NULL

  • 数据以字符串形式存储(即使是数字类型,也需手动转换)

cpp 复制代码
MYSQL_RES *res = mysql_store_result(my);
    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()

功能:获取当前行中各字段的实际长度(字节数)

cpp 复制代码
unsigned long *mysql_fetch_lengths(MYSQL_RES *result);

说明:

需在 mysql_fetch_row() 之后调用,获取当前行的字段长度数组

用于处理二进制数据或包含 \0 的字符串(避免被截断)

示例:

cpp 复制代码
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()

功能:逐个获取结果集中的字段(列)元信息

cpp 复制代码
MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result);

说明:

返回 MYSQL_FIELD 结构体指针,包含字段名、类型、长度等信息

多次调用可遍历所有字段,结束时返回 NULL

示例:

cpp 复制代码
MYSQL_FIELD *field;
while ((field = mysql_fetch_field(result))) {
    printf("字段名: %s, 类型: %d, 长度: %lu\n", 
           field->name, field->type, field->length);
}

(2)mysql_fetch_fields()

功能:一次性获取所有字段的元信息数组

cpp 复制代码
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result);

说明:

返回字段信息数组的首地址,数组长度为 mysql_num_fields(result)

适合批量获取字段信息,无需循环调用 mysql_fetch_field()

cpp 复制代码
typedef struct st_mysql_field {
  char *name;           // 字段名称(列名)
  char *org_name;       // 原始字段名(未被别名替换的名称)
  char *table;          // 字段所属的表名
  char *org_table;      // 原始表名(未被别名替换的表名)
  char *db;             // 字段所属的数据库名
  char *catalog;        // 目录名(通常为 "def")
  char *def;            // 字段的默认值(字符串形式)
  unsigned long length; // 字段的显示长度(字节数)
  unsigned long max_length; // 结果集中该字段的最大实际长度(由 mysql_store_result 计算)
  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;   // 字段的标志(如是否为 NULL、主键等,见下文详解)
  unsigned int decimals; // 小数位数(用于数值类型,如 DECIMAL)
  unsigned int charsetnr; // 字符集编号(对应 MySQL 的字符集编码)
  enum enum_field_types type; // 字段的数据类型(见下文详解)
  void *extension;      // 扩展信息(预留字段,通常不用)
} MYSQL_FIELD;

示例:

cpp 复制代码
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()

功能:在结果集中定位到指定行(随机访问)

cpp 复制代码
void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);

说明:

仅对 mysql_store_result() 获取的结果集有效(全量加载到内存)

offset 为行索引(从 0 开始),需小于 mysql_num_rows(result)

示例:定位到第 5 行(索引 4)

cpp 复制代码
mysql_data_seek(result, 4);
MYSQL_ROW row = mysql_fetch_row(result); // 获取第5行数据

(2)mysql_row_seek()

功能:通过行偏移量(MYSQL_ROW_OFFSET)定位行

cpp 复制代码
MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset);

说明:

比 mysql_data_seek() 更底层,偏移量通过 mysql_row_tell() 获取

适用于需要保存 / 恢复行位置的场景

(3)mysql_row_tell()

功能:获取当前行在结果集中的偏移量

cpp 复制代码
MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result);

说明:

返回当前行的 MYSQL_ROW_OFFSET 类型偏移量,可用于 mysql_row_seek()

8. 其他实用函数

(1)mysql_affected_rows()

功能:获取上一条 INSERT/UPDATE/DELETE 语句影响的行数

cpp 复制代码
my_ulonglong mysql_affected_rows(MYSQL *mysql);

说明:

对于 INSERT,返回插入的行数;对于 UPDATE/DELETE,返回受影响的行数

失败时返回 (my_ulonglong)-1

(2)mysql_insert_id()

功能:获取上一条 INSERT 语句生成的自增 ID(如主键 AUTO_INCREMENT)

cpp 复制代码
my_ulonglong mysql_insert_id(MYSQL *mysql);

说明:

仅对包含自增字段的表有效,且需在 INSERT 执行后立即调用

这些函数主要用于精细化处理查询结果,包括行数据读取、字段元信息获取、结果集定位等,配合之前提到的核心函数可以完成复杂的数据库操作。

相关推荐
天青Giser10 小时前
Android开发记录
android
子春一11 小时前
Flutter 与原生平台深度集成:打通 iOS 与 Android 的最后一公里
android·flutter·ios
小邓   ༽11 小时前
全场景Android测试:API、工具与案例,从TestCase到Mock类应用指南
android·android 测试·android 组件测试·mock 类·测试 api 应用·组件测试核心
享哥。14 小时前
android MVP模式代码示例
android
qq_7174100116 小时前
删除设置-流量使用情况、更多
android
QuantumLeap丶16 小时前
《Flutter全栈开发实战指南:从零到高级》- 23 -混合开发与WebView
android·flutter·ios
_李小白18 小时前
【Android FrameWork】延伸阅读:ViewRootImpl如何管理整个view世界
android
Yang-Never19 小时前
Open GL ES->以指定点为中心缩放图片纹理的完整图解
android·java·开发语言·kotlin·android studio