C中Mysql的基本api接口

    • 一、初始化
      • 参数
      • 返回值
    • 二、链接服务器
    • 三、执行SQL语句
      • 注意事项
    • 四、获取结果集
      • 4.1mysql_affected_rows和mysql_num_rows
      • 4.2mysql_store_result与mysql_free_result
      • 注意事项
      • 注意事项
        • 整体的工作流程
      • 4.3mysql_use_result()
      • 4.4mysql_field_count()
    • 五、关闭MySQL
      • 使用和区别
    • 六、错误处理
      • mysql_errno()` 和 `mysql_error()

一、初始化

创建MYSQL* 对象,使用mysql_init函数

MYSQL * mysql;
mysql_init(mysql);

参数

  • mysql:指向一个 MYSQL 结构的指针。通常传递 NULL,系统将自动为您分配和初始化一个新的 MYSQL 对象。

返回值

  • 成功:返回一个指向 MYSQL 结构的指针。
  • 失败:返回 NULL

二、链接服务器

使用函数mysql_real_connect();

MYSQL *mysql_real_connect(MYSQL *mysql,           // mysql_init() 函数的返回值const char *host,       // mysql服务器的主机地址, 写IP地址即可// localhost, null -> 代表本地连接const char *user,       // 连接mysql服务器的用户名, 默认: root const char *passwd,     // 连接mysql服务器用户对应的密码, root用户的密码const char *db,         // 要使用的数据库的名字unsigned int port,      // 连接的mysql服务器监听的端口// 如果==0, 使用mysql的默认端口3306, !=0, 使用指定的这个端口const char *unix_socket,// 本地套接字, 通常在 Windows 上使用命名管道,而在 Unix/Linux 系统上使用 Unix 套接字。如果不使用这类连接方式,此参数应设为 NULL。unsigned long client_flag); //连接时使用的特定客户端标志 通常指定为0
)

返回值:

  • 成功:返回一个指向 MYSQL 结构的指针(通常是传入的那个指针)。
  • 失败:返回 NULL,并且可以通过 mysql_error 函数来获取错误信息。

三、执行SQL语句

// 执行一个sql语句, 添删查改的sql语句都可以
int mysql_query(MYSQL *mysql, const char *query);
参数:- mysql: mysql_real_connect() 的返回值- query: 一个可以执行的sql语句, 结尾的位置不需要加 ;
返回值: - 如果查询成功,返回0。如果是查询, 结果集在mysql 对象中- 如果出现错误,返回非0值。 

注意事项

  1. 资源管理:使用 mysql_query 后,如果查询是 SELECT 类型的,你通常需要调用 mysql_store_resultmysql_use_result 来处理返回的数据。记得在不需要结果集时使用 mysql_free_result 来释放内存。
  2. 错误处理:在生产环境中,每次调用 mysql_query 后都应检查返回值,并适当处理错误。这样可以避免程序在错误状态下继续执行,导致更复杂的问题。
  3. 安全性:避免将未经验证的用户输入直接用于 SQL 语句,以防止 SQL 注入攻击。考虑使用预处理语句和参数化查询来提高安全性。

这些基本的使用方式和注意事项可以帮助你有效地使用 mysql_query 来执行数据库操作。

值得注意的是在 MySQL 中,SQL 语句的关键字(如 SELECT, INSERT, UPDATE, DELETE 等)通常是不区分大小写的,这意味着 “select” 和 “SELECT” 在 MySQL 解释器看来是相同的。然而,数据库名称、表名、列名的大小写敏感性则取决于操作系统的文件系统和 MySQL 的配置。在 Unix、Linux 系统中,它们默认是大小写敏感的,而在 Windows 系统中默认是不敏感的。

mysql_query 实质上是在客户端和 MySQL 服务器之间进行网络通信的一个接口。在使用 TCP/IP 协议的情况下,客户端通过网络向服务器发送请求,并接收服务器的响应。这个过程涉及到网络数据的发送和接收,是基于客户端-服务器模型的典型应用。

要注意的是标准 SQL 查询:如果你的查询是简单的文本,不包含二进制数据,且不需要在 SQL 语句中嵌入 null 字符,使用 mysql_query 就足够了。

而当数据中有二进制数据就需要使用mysql_real_query

int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length);
  • 灵活性:可以执行包含 null 字符的查询,因为它要求用户明确提供查询的长度。
  • 手动指定长度:用户必须指定查询字符串的长度,这允许函数处理二进制数据或包含 null 字符的数据。
  • 适用场景:非常适合执行包含 BLOB 类型数据的 SQL 语句。

四、获取结果集

4.1mysql_affected_rows和mysql_num_rows

uint64_t mysql_affected_rows(MYSQL *mysql)

mysql_affected_rows() 可能是 在使用 mysql_real_query() 或 mysql_query() 执行语句后立即调用。它返回 上一个更改、删除或插入的行数 语句(如果是 UPDATE、DELETE 或 INSERT)。对于 SELECT 语mysql_affected_rows() 有效 像 mysql_num_rows()。

对于 UPDATE 语句, 默认情况下,affected-rows 值是实际的行数 改变。如果在以下情况下指定 mysql_real_connect() 的标志 连接到 mysqld,受影响的行 value 是“找到”的行数;那是 与子句匹配。CLIENT_FOUND_ROWSWHERE

对于 REPLACE 语句, 如果新行替换了旧行,则 affected-rows 值为 2, 因为在这种情况下,在重复项之后插入了一行 已删除。

uint64_t mysql_num_rows(MYSQL_RES *result)

返回结果集中的行数。

4.2mysql_store_result与mysql_free_result

MYSQL_RES *mysql_store_result(MYSQL *mysql);
参数说明
mysql: 指向 MYSQL 结构的指针,该结构体应已通过 mysql_real_connect 函数建立了与 MySQL 服务器的连接,并已成功执行了一个查询(如通过 mysql_query)。
返回值
成功: 返回一个指向 MYSQL_RES 结构的指针,这个结构包含了从服务器返回的所有结果数据。
失败 或 查询没有产生结果集(例如执行的是 UPDATE 或 DELETE 语句): 返回 NULL。
如何将行和列的数据从结果集中取出, 需要使用其他函数

注:mysql_store_result 函数只会返回与最近一次通过 mysql_query (或其他发送 SQL 语句的函数)执行的查询相关的结果。它不会存储或回溯到之前的查询结果,而是专注于最后执行的查询。

注意事项

  1. 内存管理:使用 mysql_store_result 后,必须在不再需要结果集时调用 mysql_free_result 来释放内存。
  2. 性能考量:由于 mysql_store_result 会将所有结果数据存储在客户端内存中,对于返回大量数据的查询,这可能会消耗大量内存和网络资源。如果处理大型数据集,可能需要考虑使用 mysql_use_result,该函数允许逐行检索数据,从而减少内存占用。
  3. 错误处理:始终检查 mysql_store_result 的返回值,并使用 mysql_error 函数来诊断错误。

通过 mysql_store_result,你可以方便地在客户端处理来自 MySQL 服务器的数据,但务必注意资源管理和错误处理,以确保应用程序的稳定性和效率。

void mysql_free_result(MYSQL_RES *result);
参数说明
result: 指向 MYSQL_RES 结构的指针,该结构包含了之前查询的结果集。

mysql_free_result 函数是 MySQL C API 中用来释放由 mysql_store_resultmysql_use_result 函数分配的结果集内存的函数。这是清理和资源管理的重要一步,确保在查询处理完成后不会造成内存泄漏。

当使用 mysql_store_resultmysql_use_result 从 MySQL 服务器获取查询结果后,相关的数据会被存储在 MYSQL_RES 结构中。这个结构占用一定的内存空间,当数据处理完毕后,应该使用 mysql_free_result 来释放这些内存。如果不这样做,每次查询后未释放的内存会累积,最终可能导致内存不足或程序崩溃。

实际使用

#include <mysql.h>
#include <iostream>int main() {MYSQL *conn;MYSQL_RES *res;MYSQL_ROW row;conn = mysql_init(NULL);if (!conn) {std::cerr << "MySQL initialization failed." << std::endl;return 1;}if (!mysql_real_connect(conn, "localhost", "user", "password", "database", 0, NULL, 0)) {std::cerr << "Failed to connect to database: " << mysql_error(conn) << std::endl;mysql_close(conn);return 1;}if (mysql_query(conn, "SELECT id, name FROM users")) {std::cerr << "Query failed: " << mysql_error(conn) << std::endl;mysql_close(conn);return 1;}res = mysql_store_result(conn);if (!res) {std::cerr << "Failed to retrieve result set: " << mysql_error(conn) << std::endl;mysql_close(conn);return 1;}while ((row = mysql_fetch_row(res))) {std::cout << "ID: " << row[0] << ", Name: " << row[1] << std::endl;}// After processing the results, free the memory.mysql_free_result(res);mysql_close(conn);return 0;
}

注意事项

  1. 只释放一次:确保对每个 MYSQL_RES 结构只调用一次 mysql_free_result。重复释放可能会导致未定义行为或程序崩溃。
  2. 适时释放:尽可能在数据处理完毕后立即释放结果集,特别是在处理多个查询的情况下,避免不必要的内存占用。
  3. 检查 NULL:如果 mysql_store_resultmysql_use_result 返回 NULL,表明没有结果集需要处理,因此不应该调用 mysql_free_result
整体的工作流程
  1. 执行查询:首先使用 mysql_query 执行一个 SQL 查询。
  2. 检索结果:使用 mysql_store_result 检索查询结果并存储在 MYSQL_RES * 结构中。
  3. 处理数据:通过循环等方式处理这些结果。
  4. 释放资源:使用 mysql_free_result 释放 MYSQL_RES * 结构占用的内存。
  5. 重复操作:如果需要再次查询,回到第一步,执行新的 mysql_query,然后使用 mysql_store_result 检索新的结果。

值得注意的是如果你在调用 mysql_store_result 之后没有使用 mysql_free_result 来释放结果集的内存,然后再次进行查询并调用 mysql_store_result,这将导致内存泄漏。这是因为每次调用 mysql_store_result 都会从 MySQL 服务器获取新的结果数据,并在客户端为这些数据分配新的内存。如果旧的结果集没有被适当释放,那么这部分内存仍然被占用,尽管你已经无法再访问到这部分数据。

4.3mysql_use_result()

MYSQL_RES *mysql_use_result(MYSQL *mysql)
参数说明
mysql: 指向 MYSQL 结构的指针,该结构表示一个已连接的 MySQL 数据库。
返回值
成功:返回一个指向 MYSQL_RES 结构的指针,该结构代表结果集。
失败:返回 NULL,并且可以通过 mysql_error 函数获取错误信息。
while ((row = mysql_fetch_row(res))) {std::cout << "ID: " << row[0] << ", Name: " << row[1] << std::endl;
}
  1. 逐行处理mysql_use_result 逐行读取结果集,这意味着你不能在获取完整结果集之前执行其他查询,否则会导致未定义行为。
  2. 资源释放:使用 mysql_use_result 后,一定要调用 mysql_free_result 释放结果集,确保内存资源被适当管理。
  3. 网络延迟:因为 mysql_use_result 逐行读取数据,受网络延迟的影响可能会比 mysql_store_result 慢,但对于大结果集它能显著降低内存占用。

mysql_use_resultmysql_store_result 都是用来处理查询结果集的函数,但它们在处理方式上有以下区别:

  • mysql_store_result:一次性将整个结果集从服务器读取到客户端内存中,适用于结果集较小的情况,因为它会在客户端占用较多内存。
  • mysql_use_result:逐行从服务器读取结果集,适用于结果集较大的情况,因为它不会将整个结果集一次性加载到内存中,节省了内存占用。

4.4mysql_field_count()

在第三部分我们看到mysql_query不仅可以使用SELECT SQL语句还可以使用INSERT语句,我们对于查询语句的列数和是否是查询语句是有一定的判断需求的

unsigned int mysql_field_count(MYSQL *mysql)
  • 返回一个 unsigned int 值,表示最近执行的查询返回的列数。如果没有活动的查询或查询没有返回任何结果,则返回 0。

注意事项

  1. 正确的上下文mysql_field_count 应该在成功执行查询之后调用,以确保它返回正确的列数。如果在没有活动查询的情况下调用它,返回值将是 0。
  2. 结果集处理:当你使用 mysql_store_resultmysql_use_result 来获取结果集时,使用 mysql_field_count 可以帮助你动态地处理结果集中的数据。
  3. 查询类型:对于不返回结果集的查询(如 INSERTUPDATEDELETE),mysql_field_count 返回 0。

五、关闭MySQL

void mysql_close(MYSQL *mysql)

当你完成了数据库操作并不再需要与数据库的连接时,应该调用 mysql_close 来关闭连接。这个调用确保所有的客户端资源被适当清理,包括内部缓冲区和连接句柄。如果不关闭连接,可能会导致资源泄漏。

void mysql_library_end(void);

在所有数据库连接都已通过 mysql_close 关闭后,应调用 mysql_library_end 来清理 MySQL 客户端库使用的所有资源。这个函数主要用于多线程环境中,在所有线程都完成数据库操作并关闭连接后,由主线程调用以确保所有的客户端库资源被正确释放。

使用和区别

使用场景mysql_close 用于关闭单个数据库连接;mysql_library_end 用于在程序结束前清理客户端库。

调用时机

mysql_close:每个数据库连接在不再需要时应该被关闭。

mysql_library_end:在程序结束,所有数据库连接都已关闭后调用。

值得注意的是即使在单线程应用程序中,依然推荐在程序结束时调用 mysql_library_end。这个函数的作用不仅限于多线程环境,它负责清理 MySQL 客户端库使用的全局资源,确保所有初始化时分配的资源被适当释放,这包括内部数据结构、缓冲区等。

六、错误处理

mysql_errno()mysql_error()

mysql_errno() 返回最近一次 MySQL 函数调用所产生的错误代码。这个错误代码是一个整数值,表示特定类型的错误。

unsigned int mysql_errno(MYSQL *mysql);
返回一个 `unsigned int` 类型的错误代码。如果没有错误发生,返回值为 `0`。

mysql_error() 返回最近一次 MySQL 函数调用所产生的错误信息字符串。这个字符串描述了具体的错误情况,通常比错误代码更易读和理解。

const char *mysql_error(MYSQL *mysql);
返回一个指向描述错误的字符串的指针。如果没有错误发生,返回一个空字符串。

通过使用 mysql_errno()mysql_error(),你可以更详细地了解数据库操作中的错误,帮助调试和改进程序的错误处理能力。这两个函数在处理复杂数据库交互时尤为重要,因为它们可以提供具体的错误信息和错误代码,有助于定位和解决问题。

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

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

相关文章

001 侧边栏 地址增删改查 默认地址代码没完善

文章目录 user_index.htmlmyaccount_style.cssmyaccount_scripts.jsaddress_edit.htmlReceiverAddressReceiverAddressControllerReceiverAddressServiceImplIReceiverAddressServiceRFshopAppApplicationServletInitializerpom.xmlReceiverAddressMapper.xmlReceiverAddressMa…

文件存储解决方案-阿里云OSS

文章目录 1.菜单分级显示问题1.问题引出1.苹果灯&#xff0c;放到节能灯下面也就是id大于1272.查看菜单&#xff0c;并没有出现苹果灯3.放到灯具下面id42&#xff0c;就可以显示 2.问题分析和解决1.判断可能出现问题的位置2.找到递归返回树形菜单数据的位置3.这里出现问题的原因…

Golang 的 unmarshal 踩坑指南

文章目录 1. 写在最前面2. 字段区分出空字段还是未设置字段2.1 问题描述2.2 解决 3. 字段支持多种类型 & 按需做不同类型处理3.1 问题描述3.2 解决 4. 碎碎念5. 参考资料 1. 写在最前面 笔者最近在实现将内部通知系统的数据定义转化为产品定义的对外提供的数据结构。 举例…

算法学习笔记(5.0)-基于比较的高效排序算法-归并排序

##时间复杂度O(nlogn) 目录 ##时间复杂度O(nlogn) ##递归实现归并排序 ##原理 ##图例 ##代码实现 ##非递归实现归并排序 ##释 #代码实现 ##递归实现归并排序 ##原理 是一种基于分治策略的基础排序算法。 1.划分阶段&#xff1a;通过不断递归地将数组从中点处分开&…

Java 开发 框架安全:Spring 命令执行漏洞.(CVE-2022-22965)

什么叫 Spring 框架. Spring 框架是一个用于构建企业级应用程序的开源框架。它提供了一种全面的编程和配置模型&#xff0c;可以简化应用程序的开发过程。Spring 框架的核心特性包括依赖注入&#xff08;Dependency Injection&#xff09;、面向切面编程&#xff08;Aspect-Or…

【SpringBoot笔记43】SpringBoot应用程序集成spring-boot-admin监控工具

这篇文章,主要介绍SpringBoot应用程序如何集成spring-boot-admin监控工具。 目录 一、spring-boot-admin监控工具 1.1、创建admin-client客户端 (1)引入依赖

DeepSpeed

文章目录 一、关于 DeepSpeed1、DeepSpeed 是什么2、深度学习训练和推理的极致速度和规模3、DeepSpeed 的四大创新支柱1&#xff09;DeepSpeed 训练2&#xff09;DeepSpeed 推理3&#xff09;DeepSpeed 压缩4&#xff09;DeepSpeed4Science 4、DeepSpeed 软件套件DeepSpeed 库推…

React 第二十七章 Hook useCallback

useCallback 是 React 提供的一个 Hook 函数&#xff0c;用于优化性能。它的作用是返回一个记忆化的函数&#xff0c;当依赖发生变化时&#xff0c;才会重新创建并返回新的函数。 在 React 中&#xff0c;当一个组件重新渲染时&#xff0c;所有的函数都会被重新创建。这可能会…

青少年软件编程(Python)等级考试试卷(五级)2024年3月

2024.03 电子学会 青少年软件编程&#xff08;Python&#xff09;等级考试试卷&#xff08;五级&#xff09; 一、单选题 1.以下代码的输出结果是? ) nums list(range(100, 201)) print(nums[::10]) A.[100,110,120,130,140,150,160,170,180,190,200] B.[100,101,1…

QML笔记八

QML与C交互 QML中调用C功能、使用QML或者Quick中的C接口、使用C实现自定义的QML对象 注&#xff1a; 只有QObject的派生类才能与QML交互 QML引擎集成Qt元对象系统&#xff0c;QObject的派生子类的属性、方法、信号都可以在QML中访问 C类可以被注册为一个QML实例 C类可以被注册为…

【Web后端】请求头

1、简介 请求头&#xff08;Request Headers&#xff09;是在HTTP协议中&#xff0c;客户端&#xff08;如浏览器或应用程序&#xff09;向服务器发送请求时附带的元数据。包含了关于请求的额外信息&#xff0c;有助于客户端与服务器之间的有效通信。请求头中的信息可以让服务…

.[sqlback@memeware.net].2700勒索病毒数据怎么处理|数据解密恢复

导言&#xff1a; 随着信息技术的飞速发展&#xff0c;网络安全问题愈发严峻&#xff0c;其中勒索病毒成为了企业和个人用户面临的重要威胁之一。.[sqlbackmemeware.net].2700勒索病毒作为其中的佼佼者&#xff0c;以其独特的攻击方式和强大的破坏力&#xff0c;引起了广泛关注…

【Go语言入门学习笔记】Part1.梦开始的地方

一、前言 经过一系列的学习&#xff0c;终于有时间来学习一些新的语言&#xff0c;Go语言在现在还是比较时髦的&#xff0c;多一个技能总比不多的好&#xff0c;故有时间来学一下。 二、配置环境 按照网络中已有的配置方法配置好&#xff0c;本人采用了Jetbrain的Goland&#…

DTC 2024回顾丨zData X 多元数据库一体机:开创多元数据库时代部署新范式

导语 在2024“数据技术嘉年华”上&#xff0c;云和恩墨数据库一体机产品总经理刘宇在“数据库极致特性”专题论坛发表了题为《打造多元数据库部署新范式&#xff0c;引领一体化资源池创新之路》的演讲。他深入分析了国产数据库面临的挑战&#xff0c;并详细介绍了云和恩墨如何利…

5.10.1 Pre-Trained Image Processing Transformer

研究了低级计算机视觉任务&#xff08;例如去噪、超分辨率和去雨&#xff09;并开发了一种新的预训练模型&#xff0c;即图像处理变压器&#xff08;IPT&#xff09;。利用著名的 ImageNet 基准来生成大量损坏的图像对。 IPT 模型是在这些具有多头和多尾的图像上进行训练的。此…

Megatron-lm、DeepSpeed

1、为了训练更多的数据、更大的模型&#xff0c;提出了并行训练框架。 2、并行的方式&#xff1a;数据并行、模型并行&#xff08;张量并行、流水线并行&#xff09;。 3、Megatron-LM 综合应用了数据并行&#xff08;Data Parallelism&#xff09;&#xff0c;张量并行&…

内网安全工具之ADExplorer的使用

ADExplorer是域内一款信息查询工具&#xff0c;它是独立的可执行文件&#xff0c;无需安装。它能够列出域组织架构、用户账号、计算机账号登&#xff0c;可以帮助寻找特权用户和数据库服务器等敏感目标。 下载地址&#xff1a;http://live.sysinternals.com/ 连接 下载了ADE…

第十四届蓝桥杯大赛软件赛国赛C/C++ 大学 B 组 拼数字

//bfs只能过40%。 #include<bits/stdc.h> using namespace std; #define int long long int a,b,c,dp[2028]; struct s {int x,y,z;string m; }; map<vector<int>,int>k; signed main() {ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>a…

Java入门基础学习笔记24——While循环和do-while循环

1、While循环&#xff1a; 例1&#xff1a; package cn.ensource.loop;public class WhileDemo3 {public static void main(String[] args) {// 目标&#xff1a;掌握while循环的书写格式&#xff0c;以及理解其执行流程// 需求&#xff1a;打印多行Hello Worldint i 0;while…

EFCore_创建项目

添加依赖 Microsoft.EntityFrameworkCore Microsoft.EntityFrameworkCore.Tools(Migration工具) 根据使用的DB添加对应依赖&#xff1a; SQL Server&#xff1a;Microsoft.EntityFrameworkCore.SqlServer 添加该依赖时可不添加Microsoft.EntityFrameworkCore&#xff0c;该依…