一、连接数据库基础

1. 头文件与库文件

连接 MySQL 需包含的头文件:

#include <mysql/mysql.h>
// 部分环境也可用 #include <mysql.h> 

编译链接时,Linux 平台需指定库名:-lmysqlclient ,用于链接 MySQL 客户端函数库。

2. 初始化连接句柄

MYSQL *mysql_init(MYSQL *mysql);
  • 功能:初始化 MySQL 连接句柄。若参数为 NULL,会分配新的连接句柄并返回其指针;若参数是已有的结构,会重新初始化 。
  • 返回值:成功返回连接句柄指针,出错返回 NULL 。

3. 连接数据库

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 clientflag);
  • 参数说明:
    • mysqlmysql_init 初始化后返回的连接句柄指针。
    • host:主机名或 IP 地址,本地可填 "localhost""127.0.0.1" 或空字符串、NULL 。
    • user:数据库用户名,如管理员用户 root 。
    • passwd:用户密码 。
    • db:要连接的数据库名 。
    • port:数据库端口,默认 3306,填 0 则用默认端口 。
    • unix_socket:一般填 NULL,表示不使用 Unix 套接字或管道 。
    • clientflag:标志位,通常填 0 。
  • 返回值:成功返回与第一个参数相同的连接句柄指针,失败返回 NULL 。

4. 关闭连接

void mysql_close(MYSQL *mysql);

功能:关闭 MySQL 连接,释放相关资源,不再使用连接时调用。

二、SQL 语句执行与结果处理

1. 执行 SQL 语句

int mysql_query(MYSQL *mysql, const char *q);
  • 参数:
    • mysql:连接成功后的句柄指针。
    • q:要执行的 SQL 语句,末尾可不带分号(与命令行工具使用有区别 )。
  • 返回值:成功返回 0;若 SQL 语句含二进制数据,建议用 mysql_real_query 。

2. 提取结果

MYSQL_RES *mysql_store_result(MYSQL *mysql); // 一次性提取所有结果数据
// MYSQL_RES *mysql_use_result(MYSQL *mysql); // 一次提取一行数据(按需获取,适合大数据量)
  • 功能:mysql_query 成功执行后调用,mysql_store_result 会把结果集全部加载到客户端内存,返回指向结果集结构的指针;mysql_use_result 按需获取数据,更节省内存,但需按行读取并及时处理 。
  • 返回值:成功返回结果集指针,失败返回 NULL 。

3. 获取结果集行数

uint64_t mysql_num_rows(MYSQL_RES *res);
  • 说明:需在执行 mysql_store_result 后调用,用于获取结果集中记录的行数,无返回行则为 0 。

4. 取出结果集一行记录

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
  • 功能:从结果集中取出一行,存储到行结构中。数据处理完或出错时返回 NULL,常配合循环遍历结果集 。

5. 查看记录行列数

unsigned int mysql_field_count(MYSQL *mysql);

功能:获取结果集中一行记录的列数 。

6. 释放结果集内存

void mysql_free_result(MYSQL_RES *result);

功能:处理完结果集后调用,释放结果集占用的内存空间 。

7. 获取错误信息

unsigned int mysql_errno(MYSQL *mysql); // 返回错误码
const char *mysql_error(MYSQL *mysql); // 返回错误信息描述
  • 功能:执行操作出错时,可调用获取错误码和详细错误描述,用于调试排查问题 。

8. 简单示例

#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>int main()
{MYSQL mysql;if (mysql_init(&mysql) == NULL){printf("mysql init err\n");return 0;}if (mysql_real_connect(&mysql, "localhost", "root", "123456", "testdb", 3306, NULL, 0) == NULL){printf("connect mysql failed\n");return 0;}printf("connect mysql success\n");// char* sql = "insert into student2 values(6,'小王')";char* sql = "select * from student2";int query_res = mysql_query(&mysql, sql);if (query_res != 0){printf("query err:%s\n", mysql_error(&mysql));return 0;}// MYSQL_RES * mysql_res =mysql_use_result(&mysql);MYSQL_RES * mysql_res = mysql_store_result(&mysql);if (mysql_res == NULL){printf("result err:%s\n", mysql_error(&mysql));return 0;}// 判断返回的行数int num = mysql_num_rows(mysql_res);if (num == 0){printf("没有记录\n");return 0;}printf("得到:%d 条记录\n", num);MYSQL_ROW sqlrow;for (int i = 0; i < num; i++){sqlrow = mysql_fetch_row(mysql_res);if (sqlrow == NULL){printf("数据处理完,或者出错\n");break;}// 判断列数int fields = mysql_field_count(&mysql);for (int j = 0; j < fields; j++){printf("fieds[%d]=%s\n", j, sqlrow[j]);}}// MYSQL_ROW  sqlrow = NULL;// while( ( sqlrow = mysql_fetch_row(mysql_res)) )// {//     //printf("sqlrow[0]=%s,sqlrow[1]=%s\n",sqlrow[0],sqlrow[1]);//// }mysql_free_result(mysql_res);mysql_close(&mysql);return 0;
}

逻辑说明

  1. 初始化连接句柄,调用 mysql_init 。
  2. 调用 mysql_real_connect 连接数据库,参数填入主机、用户、密码等信息。
  3. 定义 SQL 语句,用 mysql_query 执行查询。
  4. 执行 mysql_store_result 获取结果集,判断是否为空。
  5. 调用 mysql_num_rows 获取结果行数,遍历结果集,用 mysql_fetch_row 逐行读取,结合 mysql_field_count 遍历列数据并打印。
  6. 最后用 mysql_free_result 释放结果集,mysql_close 关闭连接。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/91426.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/91426.shtml
英文地址,请注明出处:http://en.pswp.cn/web/91426.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6. 传输层协议 UDP

传输层负责数据能够从发送端传输接收端.1. 再谈端口号端口号(Port)标识了一个主机上进行通信的不同的应用程序在 TCP/IP 协议中, 用 "源 IP", "源端口号", "目的 IP", "目的端口号", "协议号" 这样一个五元组来标识一个通信…

vue 开发总结:从安装到第一个交互页面-与数据库API

vue 总结 1、安装vue&#xff1a; WinR 输入&#xff1a;cnpm install -g vue/cli 验证是否安装成功&#xff1a;vue --version 2、新建Vue工程 在对应文件夹下右击打开集成终端 输入 vue create query_system&#xff08;新建项目名字&#xff09;名称不能存在大写&#x…

运维笔记:HTTP 性能优化

一、HTTP 协议特性与性能瓶颈1.1 HTTP 协议发展历程HTTP 协议的演进直接影响着 Web 性能&#xff0c;各版本关键特性对比&#xff1a;协议版本发布时间核心特性性能优势局限性HTTP/1.01996 年无状态、短连接简单易实现每次请求需建立 TCP 连接HTTP/1.11999 年长连接、管道化减少…

ubuntu:运行gcfsd-admin守护进程需要认证,解决方法

这里有个锁子&#xff0c;每次进入都要输入密码&#xff0c;怎么解决&#xff1f; 重新挂载 /data 磁盘 sudo umount /data sudo ntfsfix /dev/sda1 sudo mount -o rw /dev/sda1 /data

1.DRF 环境安装与配置

文章目录一. Django Rest_Framework二、环境安装与配置2.1 安装 DRF2.2 创建Django项目2.3 添加 rest_framework 应用三、启动项目一. Django Rest_Framework 核心思想&#xff1a;大量缩减编写 api 接口的代码 Django REST framework 是一个建立在 Django 基础之上的 Web 应…

设计模式(十九)行为型:备忘录模式详解

设计模式&#xff08;十九&#xff09;行为型&#xff1a;备忘录模式详解备忘录模式&#xff08;Memento Pattern&#xff09;是 GoF 23 种设计模式中的行为型模式之一&#xff0c;其核心价值在于在不破坏封装性的前提下&#xff0c;捕获并外部化一个对象的内部状态&#xff0c…

Qt/C++开发监控GB28181系统/录像回放/切换播放进度立即跳转/支持8倍速播放/倍速和跳转进度无缝切换

一、前言说明 在国标监控系统中&#xff0c;录像回放过程中&#xff0c;需要切换播放进度&#xff0c;对比过很过国标系统&#xff0c;绝大部分尤其是网页版的监控系统&#xff0c;在切换进度过程中都会黑屏&#xff0c;这个体验就很不友好了&#xff0c;明明gb28181协议中就有…

【11】大恒相机SDK C++开发 ——原图像数据IFrameData内存中上下颠倒,怎么裁剪ROI 实时显示在pictureBox中

文章目录3 当内存中的 图像数据是垂直翻转的时候怎么截取ROI 并显示3.1 对ROI在原图中的位置做转换3.2 将ROI的最后一行当做开始位置&#xff0c;从底部向上复制数据3.3 完整代码3.4 图像数据在内存中上下颠倒的情况3.5 调用验证4 unsafe代码 解释及注意事项 看我另一篇文章5 C…

小架构step系列29:校验注解的组合

1 概述如果遇到某些属性需要多种校验&#xff0c;比如需要非空、符合某正则表达式、长度不能超过某值等&#xff0c;如果这种属性只有有限几个&#xff0c;那么手工把对应的校验注解都加上即可。但如果这种属性比较多&#xff0c;那么重复加这些校验注解&#xff0c;也是一种代…

网络基础19:OSPF多区域实验

一、拓扑结构1. 网络拓扑&#xff1a;骨干区域&#xff08;Area 0&#xff09;&#xff1a;连接核心设备&#xff08;AR1、AR2、AR3、AR4、AR5、AR6&#xff09;。非骨干区域&#xff1a;Area 1&#xff1a;AR5 ↔ AR9Area 2&#xff1a;AR5 ↔ AR10Area 3&#xff1a;AR6 ↔ A…

goland编写go语言导入自定义包出现: package xxx is not in GOROOT (/xxx/xxx) 的解决方案

问题 写了个自定义的包 calc.go&#xff0c;在路径 $GOPATH/go_project/src/demo_51_package/com/目录下&#xff0c;其中main.go 是main方法的入口代码 main.go 代码如下 package main import "demo_51_package/com" func main() {add : calc.Add(1, 2)println(add)…

HLS视频切片音频中断问题分析与解决方案

HLS视频切片音频中断问题分析与解决方案 问题背景 在使用FFmpeg进行HLS视频切片并通过hls.js前端播放时&#xff0c;开发者经常遇到一个典型问题&#xff1a;第一个视频切片播放正常且有声音&#xff0c;但后续切片却突然失去音频。这种现象在直播和点播场景中均有出现&#xf…

【Linux网络编程】网络层协议 - IP

目录 背景补充 协议头格式 IP报文的分片与组装 网段划分 网段划分是什么&#xff1f;为什么要进行网段划分&#xff1f; 怎么进行网段划分&#xff1f; 路由 路由表生成算法 背景补充 假设现在主机B要给主机C发送消息。在我们前面的学习中&#xff0c;一直都是将数据拷…

从“救火”到“先知”:润建曲尺运维大模型如何重构网络运维价值链

“7月18号&#xff0c;北京&#xff0c;晴&#xff0c;最高温度38摄氏度。”天气预报缓缓播报&#xff0c;商场、地铁、办公楼无不歌颂着威利斯开利的贡献&#xff0c;但这份凉爽的背后&#xff0c;离不开 “电” 的无声托举。5G毫秒级下载、丝滑的移动支付、智能电表、智能家居…

Element表格单元格类名动态设置

在 Element UI 的 el-table 组件中&#xff0c;cell-class-name 属性用于动态自定义表格单元格的 CSS 类名&#xff0c;通常用于根据数据条件设置样式。1. 基本用法在 el-table 上绑定 :cell-class-name 属性&#xff0c;值为一个函数。该函数接收一个对象参数&#xff0c;返回…

利用容器适配器实现stack和queue外加deque的介绍(STL)

文章目录前言什么是容器适配器&#xff1f;观察库中的源码那么该如何使用容器适配器呢&#xff1f;deque的简单介绍(了解)deque的原理介绍deque的优缺为什么选择deque作为stack和queue的底层默认容器&#xff1f;&#xff08;重点&#xff09;利用容器适配器实现我们自己的栈和…

【因子动物园巡礼】第12章:机器学习在因子投资中的应用(中文翻译)

【因子动物园巡礼】第12章&#xff1a;机器学习在因子投资中的应用&#xff08;中文翻译&#xff09;第12章 因子投资中的机器学习12.1 量化金融中的人工智能12.2 量化因子投资的AI化组件&#xff1a;解剖学视角12.2.1 数据源拓展与预处理12.2.2 因子研究12.2.3 因子模型12.2.4…

【Golang】用官方rate包构造简单IP限流器

文章目录使用 Go 实现基于 IP 地址的限流机制什么是 IP 限流&#xff1f;基于 rate.Limiter 实现 IP 限流1. 设计思路2. 代码实现3. 限流中间件4. 在 Gin 中使用中间件代码解释使用 Go 实现基于 IP 地址的限流机制 在高流量的服务中&#xff0c;限流是一个至关重要的环节。它不…

力扣 Pandas 挑战(6)---数据合并

本文围绕力扣的Pandas简单题集&#xff0c;解析如何用Pandas完成基础数据处理任务&#xff0c;适合Pandas初学者学习。题目1&#xff1a;1050. 合作过至少三次的演员和导演题目描述&#xff1a;ActorDirector 表&#xff1a;---------------------- | Column Name | Type | …

随笔之TDengine基准测试示例

文章目录一、基本信息二、基准测试策略三、基准测试过程1. 模拟高并发写入场景2. 模拟并发查询场景四、基准测试结论一、基本信息 TDengine 版本&#xff1a;3.3.6.13&#xff08;目前最新版本&#xff09;服务器配置&#xff1a;16核CPU&#xff0c;32GB内存&#xff0c;高IO…