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语言开发者提供一些有价值的参考和帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件授权管理中的软件激活向导示例

软件激活向导示例 在软件许可中&#xff0c;提供许可应该是简单和安全的。这适用于想要在中央许可证服务器上创建新许可证的软件开发人员&#xff0c;也适用于需要在其设备上获得许可证的最终用户。如果所讨论的系统有互联网连接&#xff0c;或是暂时的连接&#xff0c;就可以…

GB44495-2024 汽车整车信息安全技术要求 - V2X部分前置要求

背景 GB 44495-2024《汽车整车信息安全技术要求》中关于V2X&#xff08;车与外界通信&#xff09;的部分&#xff0c;主要关注于通信安全要求&#xff0c;旨在确保车辆在与外部设备进行数据交互时的信息安全。其测试大致可分为消息层&#xff08;数据无异常&#xff09;、应用…

phpstudy靶场搭建问题

前言&#xff1a; 靶场搭建遇到的问题&#xff0c;记录一下&#xff0c;可能是基础不牢吧&#xff0c;老是遇到奇奇怪怪的问题 思路&#xff1a; 跟着网上的搭建走一遍 内容&#xff1a; 目录 搭建pikachu遇到的问题 搭建pikachu遇到的问题 其实并不是第一次搭建&#x…

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

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

Hive SQL必刷练习题:留存率问题

首次登录算作当天新增&#xff0c;第二天也登录了算作一日留存。可以理解为&#xff0c;在10月1号登陆了。在10月2号也登陆了&#xff0c;那这个人就可以算是在1号留存 今日留存率 &#xff08;今日登录且明天也登录的用户数&#xff09; / 今日登录的总用户数 * 100% 解决思…

C++基础入门(二)

目录 前言 一、重载 1.函数重载 2.运算符重载 二、构造函数 1.什么是构造函数 2.带参数的构造函数 3.使用初始化列表 4.this关键字 5.new关键字 三、析构函数 1.什么是析构函数 四、静态成员变量 1.静态成员的定义 2.静态成员变量的作用 五、继承 1.继承基本概…

Redis 中 TTL 的基本知识与禁用缓存键的实现策略(Java)

目录 前言1. 基本知识2. Java代码 前言 &#x1f91f; 找工作&#xff0c;来万码优才&#xff1a;&#x1f449; #小程序://万码优才/r6rqmzDaXpYkJZF 单纯学习Redis可以看我前言的Java基本知识路线&#xff01;&#xff01; 对于Java的基本知识推荐阅读&#xff1a; java框架…

基于unity的多人家装应用的设计与实现

摘要 本课题根据主流家装应用存在的问题和结合了Unity3D引擎所具有的优势&#xff0c;在主流家装应用的基础上弥补了常见的缺憾&#xff0c;实现了一种新型的交互更强的家装展示系统。 本系统主要通过将家具模型资源和材质等资源导入Unity3D平台中&#xff0c;通过C#代码开发&a…

Three.js+Vue3+Vite应用lil-GUI调试开发3D效果(三)

前期文章中我们完成了创建第一个场景、添加轨道控制器的功能&#xff0c;接下来我们继续阐述其他的功能&#xff0c;本篇文章中主要讲述如何应用lil-GUI调试开发3D效果&#xff0c;在开始具体流程和步骤之前&#xff0c;请先查看之前的内容&#xff0c;因为该功能必须在前期内容…

采用海豚调度器+Doris开发数仓保姆级教程(满满是踩坑干货细节,持续更新)

一、采用海豚调度器Doris开发平替CDH Hdfs Yarn Hive Oozie的理由。 海豚调度器Doris离线数仓方案与CDH Hive在多个方面存在显著差异&#xff0c;以下是对这两种方案的对比分析&#xff1a; 1. 架构复杂性 CDH Hive&#xff1a;基于Hadoop生态&#xff0c;组件众多&#…

50.【8】BUUCTF WEB HardSql

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

Redis 3.2.1在Win10系统上的安装教程

诸神缄默不语-个人CSDN博文目录 这个文件可以跟我要&#xff0c;也可以从官网下载&#xff1a;https://github.com/MicrosoftArchive/redis/releases 这个是微软以前维护的Windows版Redis安装包&#xff0c;如果想要比较新的版本可以从别人维护的项目里下&#xff08;https://…

mac配置 iTerm2 使用lrzsz与服务器传输文件

mac配置 1. 安装支持rz和sz命令的lrzsz brew install lrzsz2. 下载iterm2-send-zmodem.sh和iterm2-recv-zmodem.sh两个脚本 # 克隆仓库 git clone https://github.com/aikuyun/iterm2-zmodem ~/iterm2-zmodem# 进入到仓库目录 cd ~/iterm2-zmodem# 设置脚本文件可执行权限 c…

9.7 visual studio 搭建yolov10的onnx的预测(c++)

1.环境配置 在进行onnx预测前&#xff0c;需要搭建的环境如下: 1.opencv环境的配置&#xff0c;可参考博客:9.2 c搭建opencv环境-CSDN博客 2.libtorch环境的配置&#xff0c;可参考博客&#xff1a;9.4 visualStudio 2022 配置 cuda 和 torch (c)-CSDN博客 3.cuda环境的配置…

YOLOv8从菜鸟到精通(二):YOLOv8数据标注以及模型训练

数据标注 前期准备 先打开Anaconda Navigator&#xff0c;点击Environment&#xff0c;再点击new(new是我下载anaconda的文件夹名称)&#xff0c;然后点击创建 点击绿色按钮&#xff0c;并点击Open Terminal 输入labelimg便可打开它,labelimg是图像标注工具&#xff0c;在上篇…

STM32-keil安装时遇到的一些问题以及解决方案

前言&#xff1a; 本人项目需要使用到STM32,故需配置keil 5&#xff0c;在配置时遇到了以下问题&#xff0c;并找到相应的解决方案&#xff0c;希望能够为遇到相同问题的道友提供一些解决思路 1、提示缺少&#xff08;missing&#xff09;version 5编译器 step1&#xff1a;找…

C语言结构体漫谈:从平凡中见不平凡

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文《1》 结构体的两种声明一、结构…

LabVIEW与WPS文件格式的兼容性

LabVIEW 本身并不原生支持将文件直接保存为 WPS 格式&#xff08;如 WPS 文档或表格&#xff09;。然而&#xff0c;可以通过几种间接的方式实现这一目标&#xff0c;确保您能将 LabVIEW 中的数据或报告转换为 WPS 可兼容的格式。以下是几种常见的解决方案&#xff1a; ​ 导出…

LeetCode | 栈与队列:算法入门到进阶的全解析

栈和队列作为最基础的数据结构&#xff0c;不仅简单直观&#xff0c;还在算法世界中扮演着举足轻重的角色。无论是处理括号匹配问题、滑动窗口、还是实现先进先出的任务调度&#xff0c;栈与队列都是核心工具。 在本篇文章中&#xff0c;我们将以 LeetCode 中的经典题目为例&am…

得物App再迎开放日,全流程体验正品查验鉴别

近日&#xff0c;得物App超级品质保障中心再度迎来了开放日活动。近60位得物App的用户与粉丝齐聚超级品质保障中心&#xff0c;全流程体验正品查验鉴别。开放日当天&#xff0c;参与者有机会近距离观察得物App的商品质检区、鉴别区、收发流转区、实验室和正品库等关键功能区&am…