`MYSQL`、`MYSQL_RES` 和 `MYSQL_FIELD`的含义与使用案例

在 MySQL C API 中,MYSQL、MYSQL_RES 和 MYSQL_FIELD 是三个核心数据结构,分别代表数据库连接、查询结果集和字段元数据。以下是它们的详细解释:


1. MYSQL - 数据库连接句柄

作用:表示与 MySQL 服务器的连接,是操作数据库的入口点。

关键属性和操作:

c 复制代码
typedef struct st_mysql {
  NET net;                 // 网络连接信息
  char *host;              // 服务器主机名
  char *user;              // 用户名
  char *passwd;            // 密码
  char *db;                // 当前数据库
  unsigned int port;       // 端口号
  unsigned long client_flag; // 连接标志
  // ... 其他内部状态字段
} MYSQL;

常用操作函数:

c 复制代码
MYSQL *mysql = mysql_init(NULL);                   // 初始化连接
mysql_real_connect(mysql, "host", "user", "pass", "db", port, NULL, 0); // 建立连接
mysql_query(mysql, "SELECT * FROM table");         // 执行查询
mysql_close(mysql);                                // 关闭连接

2. MYSQL_RES - 查询结果集

作用 :表示 SELECT、SHOW 等查询返回的结果集。

关键属性和操作:

c 复制代码
typedef struct st_mysql_res {
  uint64_t row_count;     // 结果集中的行数
  MYSQL_FIELD *fields;    // 字段元数据数组
  MYSQL_DATA *data;       // 结果数据
  // ... 其他内部字段
} MYSQL_RES;

常用操作函数:

c 复制代码
MYSQL_RES *result = mysql_store_result(mysql);    // 获取完整结果集
// 或
MYSQL_RES *result = mysql_use_result(mysql);      // 获取流式结果集

int num_fields = mysql_num_fields(result);        // 获取字段数量
long long num_rows = mysql_num_rows(result);      // 获取行数

MYSQL_ROW row = mysql_fetch_row(result);          // 获取一行数据
mysql_free_result(result);                        // 释放结果集

3. MYSQL_FIELD - 字段元数据

作用:描述结果集中每个字段的结构信息(列定义)。

关键属性:

c 复制代码
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;        // 字段标志(NOT NULL、PRIMARY KEY等)
  unsigned int decimals;     // 小数位数
  unsigned int charsetnr;    // 字符集编号
  enum enum_field_types type; // 字段类型
} MYSQL_FIELD;

常用操作函数:

c 复制代码
MYSQL_FIELD *fields = mysql_fetch_fields(result);  // 获取所有字段信息
unsigned int num_fields = mysql_num_fields(result);

for (int i = 0; i < num_fields; i++) {
  printf("Field %d: %s (Type: %d)\n", 
         i, fields[i].name, fields[i].type);
}

三者的工作关系

执行查询 包含 包含 MYSQL MYSQL_RES MYSQL_FIELD 数组 MYSQL_ROW 数据

  1. 连接阶段 :通过 MYSQL 对象建立连接
  2. 查询阶段:执行 SQL 语句
  3. 结果处理 :
    • 通过 MYSQL_RES 获取结果集
    • 通过 MYSQL_FIELD 获取字段结构信息
    • 通过 mysql_fetch_row() 获取实际数据行

完整使用示例

c 复制代码
#include <mysql/mysql.h>
#include <stdio.h>

int main() {
    MYSQL *conn = mysql_init(NULL);
    if (!mysql_real_connect(conn, "localhost", "user", "pass", "db", 0, NULL, 0)) {
        fprintf(stderr, "连接失败: %s\n", mysql_error(conn));
        return 1;
    }

    // 执行查询
    if (mysql_query(conn, "SELECT id, name, email FROM users")) {
        fprintf(stderr, "查询失败: %s\n", mysql_error(conn));
        return 1;
    }

    // 获取结果集
    MYSQL_RES *result = mysql_store_result(conn);
    if (!result) {
        fprintf(stderr, "获取结果集失败: %s\n", mysql_error(conn));
        return 1;
    }

    // 获取字段信息
    MYSQL_FIELD *fields = mysql_fetch_fields(result);
    int num_fields = mysql_num_fields(result);

    // 打印表头
    for (int i = 0; i < num_fields; i++) {
        printf("%-15s", fields[i].name);
    }
    printf("\n------------------------------------------------\n");

    // 打印数据
    MYSQL_ROW row;
    while ((row = mysql_fetch_row(result))) {
        for (int i = 0; i < num_fields; i++) {
            printf("%-15s", row[i] ? row[i] : "NULL");
        }
        printf("\n");
    }

    // 清理资源
    mysql_free_result(result);
    mysql_close(conn);
    return 0;
}

字段类型常量(部分)

常量名 值 对应 SQL 类型
MYSQL_TYPE_TINY 1 TINYINT
MYSQL_TYPE_SHORT 2 SMALLINT
MYSQL_TYPE_LONG 3 INT
MYSQL_TYPE_FLOAT 4 FLOAT
MYSQL_TYPE_DOUBLE 5 DOUBLE
MYSQL_TYPE_STRING 254 CHAR/VARCHAR
MYSQL_TYPE_BLOB 252 BLOB/TEXT
MYSQL_TYPE_TIMESTAMP 7 TIMESTAMP
MYSQL_TYPE_DATE 10 DATE
MYSQL_TYPE_TIME 11 TIME
MYSQL_TYPE_DATETIME 12 DATETIME

重要注意事项

  1. 资源释放:

    • 必须调用 mysql_free_result() 释放结果集
    • 必须调用 mysql_close() 关闭连接
  2. 结果集生命周期:

    c 复制代码
    // 错误!result 在 if 块结束后被释放
    if (mysql_query(conn, "SELECT ...")) {
        MYSQL_RES *result = mysql_store_result(conn);
    }
    // 此处 result 已失效
  3. 二进制数据:

    • 使用 mysql_real_escape_string() 处理二进制数据
    • 对于 BLOB 类型,结果以 char* 形式返回
  4. 空值处理:

    c 复制代码
    if (row[i] == NULL) {
        // 处理空值
    }

掌握这三个核心结构及其关系是使用 MySQL C API 进行高效数据库开发的基础。

相关推荐
花间相见16 小时前
【计算基础|Redis01】【上手】安装连接、配置与通用命令
数据库·后端·面试
geovindu16 小时前
Pivoting and Unpivoting Data in SQL using postgreSQL 18
大数据·数据库·数据仓库·sql·postgresql·数据库开发·数据库架构
我命由我1234516 小时前
6-3.Python 异常处理 - 异常处理进阶(else 块与 finally 块、异常传递、自定义异常)
开发语言·前端·数据库·后端·python·学习·java-ee
Elastic 中国社区官方博客16 小时前
Elastic 重大事件功能如何将 100 条日志样本转化为检测规则
大数据·运维·数据库·人工智能·elasticsearch·搜索引擎
adinnet202616 小时前
持续智能问数:多轮对话状态管理、下钻钻取与经营驾驶舱的演进
javascript·数据库·人工智能
系统集成-鹰翔17 小时前
ERP接口月度统计少了零单月份:SQLite分组与最近三个月均值排查
javascript·数据库·经验分享·后端
ClouGence17 小时前
支付机构为什么需要数据同步:从监管报送到跨云业务协作
数据库·数据分析
wuyk55517 小时前
PyQt6-第14讲-数据库与Excel双向同步
数据库·python·ui·excel·pyqt
乐观的Terry17 小时前
AI翻译助手-JWT与redis无状态认证
数据库·redis·缓存
胖头鱼的鱼缸(尹海文)18 小时前
胖头鱼的技术专栏-482 Oracle AI DB 23.26.4新特性一览(20261027)
数据库·人工智能·oracle