C语言的数据库交互

C语言的数据库交互

引言

在现代的软件开发中,数据库是应用程序的重要组成部分。无论是小型的个人项目还是大型的企业级应用,数据的存储、查询和管理都需要有效的数据库系统。在众多编程语言中,C语言以其高效、灵活和底层操作的特性,被广泛应用于系统编程、嵌入式开发等领域。当然,C语言在数据库交互方面也是非常强大的。本文将深入探讨C语言与数据库的交互,包括常用的数据库及其驱动,数据库操作的基本流程,常见的数据库操作示例等。

C语言简介

C语言是一种通用的编程语言,最初由丹尼斯·里奇(Dennis Ritchie)在1972年开发。由于其高效性和可移植性,C语言广泛应用于系统软件、应用程序以及嵌入式系统的开发。C语言的核心特点包括:

  1. 低级操作:C语言允许直接操作内存,这在与数据库的交互中提供了高度的灵活性。
  2. 高效性:相较于许多其他高级语言,C语言的执行速度更快,适合对性能要求较高的应用。
  3. 丰富的库支持:尽管C语言本身并不直接提供数据库接口,但可以通过第三方库与各种数据库进行交互。

常用数据库系统

在与C语言交互时,开发者可以选择多种数据库系统,常见的包括:

  1. MySQL:开源关系型数据库,广泛应用于Web开发。
  2. PostgreSQL:开源对象关系型数据库,支持复杂的数据类型和事务处理。
  3. SQLite:轻型数据库,适合嵌入式应用。
  4. MongoDB:开源的NoSQL数据库,适合大数据和非结构化数据的处理。
  5. Oracle:广泛使用的商业关系型数据库,适合大型企业。

本文将主要以MySQL和SQLite为例,解析如何使用C语言进行数据库交互。

数据库驱动

为了让C语言与数据库进行交互,需要使用相应的数据库驱动。数据库驱动是实现程序与数据库之间有效通讯的中介。对于C语言,主要有以下几种驱动:

  1. MySQL C API:MySQL官方提供的C语言接口,允许开发者执行SQL语句,管理连接等。
  2. SQLite C API:SQLite自带的C语言API,提供了轻量级的数据库管理功能。
  3. PostgreSQL C API:PostgreSQL官方提供的C语言接口,支持复杂查询和事务。
  4. ODBC:开放数据库连接(Open Database Connectivity),提供通用的API接口,能够与多种数据库系统进行交互。

在这篇文章中,我们将主要使用MySQL和SQLite的C语言API进行数据库交互的演示。

数据库的基本操作流程

与数据库交互的基本流程通常包括以下步骤:

  1. 连接数据库:创建一个到数据库的链接。
  2. 执行SQL语句:通过链接执行各种数据库操作,如查询、插入、更新和删除。
  3. 处理结果:根据执行的操作处理返回的结果。
  4. 关闭连接:操作完成后,关闭数据库链接,释放资源。

以下将对这各个步骤进行详细讲解,并提供示例代码。

连接数据库

连接数据库的第一步是初始化数据库连接。以MySQL为例,连接的基本步骤如下:

  1. 引入 mysql/mysql.h 头文件。
  2. 创建并初始化MYSQL对象。
  3. 使用 mysql_real_connect 函数建立到数据库的连接。

示例代码:

```c

include

include

include

MYSQL *conn;

void connect_to_database() { conn = mysql_init(NULL); if (conn == NULL) { fprintf(stderr, "mysql_init() failed\n"); exit(EXIT_FAILURE); }

if (mysql_real_connect(conn, "localhost", "user", "password", "testdb", 0, NULL, 0) == NULL) {fprintf(stderr, "mysql_real_connect() failed\n");mysql_close(conn);exit(EXIT_FAILURE);
}printf("Connected to the database successfully!\n");

} ```

执行SQL语句

连接到数据库后,就可以开始执行SQL语句了。不同的数据库操作可以使用不同的mysql函数来完成。

示例代码:

查询操作

```c void query_database() { if (mysql_query(conn, "SELECT * FROM users")) { fprintf(stderr, "SELECT * failed. Error: %s\n", mysql_error(conn)); return; }

MYSQL_RES *result = mysql_store_result(conn);
if (result == NULL) {fprintf(stderr, "mysql_store_result() failed. Error: %s\n", mysql_error(conn));return;
}int num_fields = mysql_num_fields(result);
MYSQL_ROW row;while ((row = mysql_fetch_row(result))) {for (int i = 0; i < num_fields; i++) {printf("%s ", row[i] ? row[i] : "NULL");}printf("\n");
}mysql_free_result(result);

} ```

插入操作

```c void insert_into_database(const char* name, int age) { char query[256]; snprintf(query, sizeof(query), "INSERT INTO users(name, age) VALUES('%s', %d)", name, age);

if (mysql_query(conn, query)) {fprintf(stderr, "INSERT failed. Error: %s\n", mysql_error(conn));
} else {printf("Inserted %s, %d into users table successfully!\n", name, age);
}

} ```

处理结果

在查询操作之后,我们会得到一个结果集,可以通过函数 mysql_fetch_row 循环读取每一行的数据。每一行的数据以数组的形式返回,数组的每个元素都对应数据库表的每一列。

关闭连接

操作完成后,要确保关闭数据库连接,防止资源泄露。

示例代码:

c void close_connection() { mysql_close(conn); printf("Connection closed.\n"); }

完整的示例

将上述代码整合成一个完整的示例程序:

```c

include

include

include

MYSQL *conn;

void connect_to_database() { conn = mysql_init(NULL); if (conn == NULL) { fprintf(stderr, "mysql_init() failed\n"); exit(EXIT_FAILURE); }

if (mysql_real_connect(conn, "localhost", "user", "password", "testdb", 0, NULL, 0) == NULL) {fprintf(stderr, "mysql_real_connect() failed\n");mysql_close(conn);exit(EXIT_FAILURE);
}printf("Connected to the database successfully!\n");

}

void query_database() { if (mysql_query(conn, "SELECT * FROM users")) { fprintf(stderr, "SELECT * failed. Error: %s\n", mysql_error(conn)); return; }

MYSQL_RES *result = mysql_store_result(conn);
if (result == NULL) {fprintf(stderr, "mysql_store_result() failed. Error: %s\n", mysql_error(conn));return;
}int num_fields = mysql_num_fields(result);
MYSQL_ROW row;while ((row = mysql_fetch_row(result))) {for (int i = 0; i < num_fields; i++) {printf("%s ", row[i] ? row[i] : "NULL");}printf("\n");
}mysql_free_result(result);

}

void insert_into_database(const char* name, int age) { char query[256]; snprintf(query, sizeof(query), "INSERT INTO users(name, age) VALUES('%s', %d)", name, age);

if (mysql_query(conn, query)) {fprintf(stderr, "INSERT failed. Error: %s\n", mysql_error(conn));
} else {printf("Inserted %s, %d into users table successfully!\n", name, age);
}

}

void close_connection() { mysql_close(conn); printf("Connection closed.\n"); }

int main() { connect_to_database(); insert_into_database("Alice", 30); query_database(); close_connection(); return 0; } ```

SQLite的数据库交互

SQLite是一种轻型的数据库系统,嵌入式特性使其非常适合于小型应用程序和移动设备。与MySQL类似,SQLite也提供了C语言的API,使用方法也大体相似。以下是使用SQLite的基本示例。

连接数据库

```c

include

sqlite3 *db;

void connect_to_sqlite() { int rc = sqlite3_open("test.db", &db); if (rc) { fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); return; } printf("Opened database successfully!\n"); } ```

执行SQL语句

查询操作

```c void query_sqlite() { const char sql = "SELECT * FROM users"; sqlite3_stmt stmt;

int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
if (rc != SQLITE_OK) {fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));return;
}while (sqlite3_step(stmt) == SQLITE_ROW) {const unsigned char *name = sqlite3_column_text(stmt, 0);int age = sqlite3_column_int(stmt, 1);printf("%s %d\n", name, age);
}sqlite3_finalize(stmt);

} ```

插入操作

```c void insert_into_sqlite(const char name, int age) { const char sql = "INSERT INTO users (name, age) VALUES (?, ?)"; sqlite3_stmt *stmt;

int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
if (rc != SQLITE_OK) {fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));return;
}sqlite3_bind_text(stmt, 1, name, -1, SQLITE_STATIC);
sqlite3_bind_int(stmt, 2, age);rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE) {fprintf(stderr, "Execution failed: %s\n", sqlite3_errmsg(db));
} else {printf("Inserted %s, %d into users table successfully!\n", name, age);
}sqlite3_finalize(stmt);

} ```

关闭连接

操作完成后,也要确保关闭SQLite连接。

c void close_sqlite_connection() { sqlite3_close(db); printf("SQLite connection closed.\n"); }

整合示例

将SQLite的部分整合成一个完整的示例程序:

```c

include

include

sqlite3 *db;

void connect_to_sqlite() { int rc = sqlite3_open("test.db", &db); if (rc) { fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); return; } printf("Opened database successfully!\n"); }

void query_sqlite() { const char sql = "SELECT * FROM users"; sqlite3_stmt stmt;

int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
if (rc != SQLITE_OK) {fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));return;
}while (sqlite3_step(stmt) == SQLITE_ROW) {const unsigned char *name = sqlite3_column_text(stmt, 0);int age = sqlite3_column_int(stmt, 1);printf("%s %d\n", name, age);
}sqlite3_finalize(stmt);

}

void insert_into_sqlite(const char name, int age) { const char sql = "INSERT INTO users (name, age) VALUES (?, ?)"; sqlite3_stmt *stmt;

int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
if (rc != SQLITE_OK) {fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));return;
}sqlite3_bind_text(stmt, 1, name, -1, SQLITE_STATIC);
sqlite3_bind_int(stmt, 2, age);rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE) {fprintf(stderr, "Execution failed: %s\n", sqlite3_errmsg(db));
} else {printf("Inserted %s, %d into users table successfully!\n", name, age);
}sqlite3_finalize(stmt);

}

void close_sqlite_connection() { sqlite3_close(db); printf("SQLite connection closed.\n"); }

int main() { connect_to_sqlite(); insert_into_sqlite("Bob", 25); query_sqlite(); close_sqlite_connection(); return 0; } ```

总结

在与数据库进行交互时,C语言通过数据库驱动可以实现多种复杂的操作。虽然C语言在语法和使用上比某些高级语言更为繁琐,但它提供的高效性和底层控制能力使得其在系统级开发中依然占据重要角色。通过本文的示例,开发者可以初步了解C语言如何与常见的数据库(如MySQL和SQLite)进行交互,并进行简单的数据库操作。

借助C语言强大的标准库和第三方库,开发者可以构建出高效、稳定的大型系统应用。在未来的开发中,掌握C语言的数据库交互无疑会为开发者打开更广阔的技术视野。无论是小型应用还是复杂系统,理解数据库操作的基本流程和方法都是极为重要的技能。希望本文能为广大C语言开发者提供一些有价值的参考和帮助。

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

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

相关文章

ROS1学习记录

我使用的是ubuntu20.04下的ROS Noetic版本&#xff0c;是ROS 1 的最后一个长期支持&#xff08;LTS&#xff09;版本&#xff0c;将于2025年5月停止维护 一&#xff0c;Linux系统基本操作 ctrlaltt快速打开终端 1&#xff0c;pwd命令 查看当前终端所在路径 使用方式&#…

Go Ebiten小游戏开发:贪吃蛇

贪吃蛇是一款经典的小游戏&#xff0c;玩法简单却充满乐趣。本文将介绍如何使用 Go 语言和 Ebiten 游戏引擎开发一个简单的贪吃蛇游戏。通过这个项目&#xff0c;你可以学习到游戏开发的基本流程、Ebiten 的使用方法以及如何用 Go 实现游戏逻辑。 项目简介 贪吃蛇的核心玩法是…

ASP.NET Core - .NET 6 以上版本的入口文件

ASP.NET Core - .NET 6 以上版本的入口文件 自从.NET 6 开始&#xff0c;微软对应用的入口文件进行了调整&#xff0c;移除了 Main 方法和 Startup 文件&#xff0c;使用顶级语句的写法&#xff0c;将应用初始化的相关配置和操作全部集中在 Program.cs 文件中&#xff0c;如下&…

Chapter1:初见C#

参考书籍&#xff1a;《C#边做边学》&#xff1b; 1.初见C# 1.1 C#简介 C # {\rm C\#} C#编写了许多完成常用功能的程序放在系统中&#xff0c;把系统中包含的内容按功能分成多个部分&#xff0c;每部分放在一个命名空间中&#xff0c;导入命名空间语法格式如下&#xff1a; /…

React封装倒计时按钮

背景 在开发过程中&#xff0c;经常需要使用到倒计时的场景&#xff0c;当用户点击后&#xff0c;按钮进行倒计时&#xff0c;然后等待邮件或者短信发送&#xff0c;每次都写重复代码&#xff0c;会让代码显得臃肿&#xff0c;所以封装一个组件来减少耦合 创建一个倒计时组件…

【编译构建】用cmake编译libjpeg动态库并实现转灰度图片

先编译出libjepg动态库 1、下载libjpeg源码: https://github.com/libjpeg-turbo/libjpeg-turbo 2、编译出动态库或静态库 写一个编译脚本&#xff0c;用cmake构建。 #!/bin/bash# 定义变量 SOURCE_DIR"/home/user/libjpeg-turbo-main" BUILD_DIR"${SOURCE_…

ORB-SLAM2源码学习: Frame.cc: cv::Mat Frame::UnprojectStereo将某个特征点反投影到三维世界坐标系中

前言 这个函数是在跟踪线程中更新上一帧的函数中被调用。 1.函数声明 cv::Mat Frame::UnprojectStereo(const int &i) 2.函数定义 1.获取这个特征点的深度值。 const float z mvDepth[i];深度值由双目或 RGB-D 传感器获取。 在双目情况下&#xff0c;这个深度来自…

单片机存储器和C程序编译过程

1、 单片机存储器 只读存储器不是并列关系&#xff0c;是从ROM发展到FLASH的过程 RAM ROM 随机存储器 只读存储器 CPU直接存储和访问 只读可访问不可写 临时存数据&#xff0c;存的是CPU正在使用的数据 永久存数据&#xff0c;存的是操作系统启动程序或指令 断电易失 …

【Excel】【VBA】双列排序:坐标从Y从大到小排列之后相同Y坐标的行再对X从小到大排列

Excel VBA 双列排序 功能概述 这段VBA代码实现了Excel中的双列排序功能&#xff0c;具体是&#xff1a; 跳过前3行表头先按C列数据从大到小排序在C列值相同的情况下&#xff0c;按B列从大到小排序排序时保持整行数据的完整性 流程图 #mermaid-svg-XJERemQluZlM4K8l {font-fa…

【25考研】西南交通大学软件工程复试攻略!

一、复试内容 复试对考生的既往学业情况、外语听说交流能力、专业素质和科研创新能力&#xff0c;以及综合素质和一贯表现等进行全面考查,主要考核内容包括思想政治素质和道德品质、外语听说能力、专业素质和能力&#xff0c;综合素质及能力。考核由上机考试和面试两部分组成&a…

运行fastGPT 第四步 配置ONE API 添加模型

上次已经装好了所有的依赖和程序。 下面在网页中配置One API &#xff0c;这个是大模型的接口。配置好了之后&#xff0c;就可以配置fastGPT了。 打开 OneAPI 页面 添加模型 这里要添加具体的付费模型的API接口填进来。 可以通过ip:3001访问OneAPI后台&#xff0c;**默认账号…

硬件知识:显示器发展历程介绍

目录 一、阴极射线管显示器(CRT) 二、等离子显示器(PDP) 三、液晶显示器(LCD) 四、传统LED显示器(LED) 五、有机发光二极管显示器(OLED) 六、量子点显示器(QD) 七、MiniLED显示器(MiniLED) 八、MicroLED显示器(MicroLED) 总结 显示器作为电子设备与人…

修复5.0.0r 64位版本浏览器和一些库找不到的问题

笔者在使用5.0.0r版本64位时踩过不少坑&#xff0c;先将相关修复方法分享 浏览器无法使用 base/startup/appspawn/appdata-sandbox64.json添加沙箱配置 相关修复pr:https://gitee.com/openharmony/startup_appspawn/pulls/1854/files {"src-path" : "/system…

【Flink系列】4. Flink运行时架构

4. Flink运行时架构 4.1 系统架构 Flink运行时架构——Standalone会话模式为例 1&#xff09;作业管理器&#xff08;JobManager&#xff09; JobManager是一个Flink集群中任务管理和调度的核心&#xff0c;是控制应用执行的主进程。也就是说&#xff0c;每个应用都应该被…

IP层之分片包的整合处理

前言 在上一章节中&#xff0c;笔者就IP层的接收代码逻辑做了简单介绍&#xff0c;并对实现代码进行了逻辑梳理以及仿真测试&#xff0c;并且在上一章节中&#xff0c;就IP层的分片包问题&#xff0c;如何确定分片包是否存在已经进行了简单介绍&#xff0c;并在接收模块中&…

使用jupyter notebook没有正常打开浏览器的几种情况解决

迅速记录前期 1.下载 https://www.anaconda.com/products/individual 2.安装 直接默认安装就行 3.打开jupyter notebook 在开始菜单里面可以找到 4.遇到的问题解决 1.运行jupyter notebook&#xff0c;黑窗口自动关了 每次黑窗口迅速的加载完就自己关掉了 也没有打开新…

50.【8】BUUCTF WEB HardSql

进入靶场 随便输输 上order by ????????&#xff0c;被过滤了,继续找其他也被过滤的关键字 #&#xff0c;-- -&#xff0c;-- 都不行&#xff0c;尝试其他特殊字符后发现and&#xff0c;union&#xff0c;select&#xff0c;空格&#xff0c;都被过滤了 如下 我就不知…

中国石油大学(华东)自动评教工具(涵盖爬虫的基础知识,适合练手)

我开发了一个用于自动评教的工具&#xff0c;大家可以试着用用&#xff0c;下面是链接。 https://github.com/restrain11/auto_teachingEvaluate 可以点个星吗&#xff0c;感谢&#xff01;&#x1fae1; 以下是我在开发过程中学到的知识 以及 碰到的部分问题 目录 动态爬虫和静…

深入云电脑PC Farm技术探讨,以阿里云、华为云、ToDesk为例

&#x1f31d;引言 近年来&#xff0c;云计算技术的飞速发展为各行各业的数字化转型带来了全新机遇&#xff0c;其中云电脑作为一种虚拟化桌面解决方案&#xff0c;逐渐成为个人用户与企业的核心选择。从远程办公、在线教育到高性能计算需求&#xff0c;云电脑通过为用户提供随…

RK3568平台(音频篇)lineout无声调试

一.声音硬件框架 硬件HP_MUTE已强制拉低。 二.设备树配置 es8388_sound: es8388-sound {status = "okay";compatible = "rockchip,multicodecs-card";rockchip,card-name = "rockchip-es8388";hp-det-gpio = <&gpio1 RK_PD2 GPIO_ACT…