C语言访问MySQL数据库简单实例
《C语言访问MySQL数据库简单实例》
在当今信息化时代,数据库技术已成为软件开发的核心环节。MySQL作为开源关系型数据库的代表,凭借其高性能、易用性和跨平台特性,广泛应用于Web开发、嵌入式系统等领域。而C语言作为系统级编程的经典语言,因其高效性和对硬件的直接控制能力,常用于底层开发或需要高性能的场景。将C语言与MySQL结合,能够开发出高效、稳定的数据库交互程序。本文将通过一个完整的实例,详细介绍如何在C语言环境中连接MySQL数据库,执行增删改查(CRUD)操作,并分析关键技术点与常见问题解决方案。
一、环境准备
在开始编写代码前,需完成以下环境配置:
1. 安装MySQL数据库:从MySQL官网下载社区版安装包,根据操作系统选择对应版本(如Windows的ZIP Archive或Linux的RPM/DEB包)。安装过程中需记录root用户密码,后续连接数据库时使用。
2. 安装MySQL C Connector:MySQL官方提供了C语言的连接库(MySQL Connector/C),用于在C程序中操作数据库。可从MySQL官网下载对应平台的库文件(如Windows的.zip或Linux的.tar.gz),解压后需将头文件(include)和库文件(lib)路径添加到编译器的搜索路径中。
3. 开发工具选择:推荐使用支持C语言的IDE(如Code::Blocks、Visual Studio)或文本编辑器(如VSCode)配合GCC编译器。以GCC为例,编译时需链接MySQL客户端库(`-lmysqlclient`)。
二、连接MySQL数据库
连接MySQL数据库的核心步骤包括初始化连接句柄、设置连接参数、执行连接操作。以下是一个完整的连接示例:
#include
#include
#include
int main() {
MYSQL *conn; // 定义连接句柄
conn = mysql_init(NULL); // 初始化连接
if (conn == NULL) {
fprintf(stderr, "mysql_init() failed\n");
exit(1);
}
// 连接数据库
if (mysql_real_connect(conn, "localhost", "root", "password",
"testdb", 0, NULL, 0) == NULL) {
fprintf(stderr, "mysql_real_connect() failed: %s\n", mysql_error(conn));
mysql_close(conn);
exit(1);
}
printf("Connected to MySQL database successfully!\n");
// 关闭连接
mysql_close(conn);
return 0;
}
代码解析:
1. `mysql_init()`:初始化一个MYSQL连接句柄,返回指向该句柄的指针。若失败返回NULL。
2. `mysql_real_connect()`:建立与MySQL服务器的连接。参数依次为:连接句柄、主机名(localhost表示本地)、用户名、密码、数据库名、端口号(0表示默认3306)、Unix套接字文件(NULL表示不使用)、客户端标志(0表示默认)。连接失败时可通过`mysql_error()`获取错误信息。
3. `mysql_close()`:关闭连接并释放资源。务必在程序结束前调用,避免内存泄漏。
三、执行SQL查询
连接数据库后,可通过`mysql_query()`执行SQL语句。以下示例演示如何创建表、插入数据、查询数据:
1. 创建表
char *create_table_sql = "CREATE TABLE IF NOT EXISTS users ("
"id INT AUTO_INCREMENT PRIMARY KEY,"
"name VARCHAR(50) NOT NULL,"
"age INT)";
if (mysql_query(conn, create_table_sql)) {
fprintf(stderr, "CREATE TABLE failed: %s\n", mysql_error(conn));
}
2. 插入数据
char *insert_sql = "INSERT INTO users (name, age) VALUES ('Alice', 25)";
if (mysql_query(conn, insert_sql)) {
fprintf(stderr, "INSERT failed: %s\n", mysql_error(conn));
}
3. 查询数据
查询操作需分两步:执行查询语句,然后遍历结果集。
if (mysql_query(conn, "SELECT * FROM users")) {
fprintf(stderr, "SELECT failed: %s\n", mysql_error(conn));
} else {
MYSQL_RES *result = mysql_store_result(conn); // 获取结果集
if (result == NULL) {
fprintf(stderr, "mysql_store_result() failed: %s\n", mysql_error(conn));
} else {
MYSQL_ROW row; // 定义行变量
while ((row = mysql_fetch_row(result)) != NULL) {
printf("ID: %s, Name: %s, Age: %s\n", row[0], row[1], row[2]);
}
mysql_free_result(result); // 释放结果集
}
}
关键函数说明:
1. `mysql_store_result()`:将查询结果全部获取到客户端,返回一个`MYSQL_RES`结构体指针。若结果集过大,可考虑使用`mysql_use_result()`逐行获取以减少内存占用。
2. `mysql_fetch_row()`:从结果集中获取下一行数据,返回`MYSQL_ROW`类型(本质是字符串数组)。行数据顺序与SELECT语句中的列顺序一致。
3. `mysql_free_result()`:释放结果集占用的内存。务必在不再需要结果时调用。
四、更新与删除数据
更新和删除数据的操作与插入类似,均通过`mysql_query()`执行SQL语句。
1. 更新数据
char *update_sql = "UPDATE users SET age = 26 WHERE name = 'Alice'";
if (mysql_query(conn, update_sql)) {
fprintf(stderr, "UPDATE failed: %s\n", mysql_error(conn));
}
2. 删除数据
char *delete_sql = "DELETE FROM users WHERE name = 'Alice'";
if (mysql_query(conn, delete_sql)) {
fprintf(stderr, "DELETE failed: %s\n", mysql_error(conn));
}
五、错误处理与资源管理
在实际开发中,完善的错误处理和资源管理至关重要。以下是一些关键原则:
1. 检查所有MySQL API调用的返回值。例如,`mysql_query()`返回0表示成功,非0表示失败。
2. 使用`mysql_error()`获取详细的错误信息,便于调试。
3. 确保在程序退出前关闭所有连接和释放所有资源(如结果集)。可采用类似以下的结构:
MYSQL *conn = mysql_init(NULL);
if (!conn) { /* 处理错误 */ }
if (mysql_real_connect(conn, ...) != NULL) {
// 执行数据库操作
} else {
fprintf(stderr, "%s\n", mysql_error(conn));
}
mysql_close(conn); // 确保关闭连接
六、完整实例:学生信息管理系统
以下是一个完整的C语言访问MySQL的实例,实现学生信息的增删改查功能:
#include
#include
#include
#include
#define HOST "localhost"
#define USER "root"
#define PASS "password"
#define DB "student_db"
void init_db(MYSQL **conn) {
*conn = mysql_init(NULL);
if (*conn == NULL) {
fprintf(stderr, "mysql_init() failed\n");
exit(1);
}
if (mysql_real_connect(*conn, HOST, USER, PASS, DB, 0, NULL, 0) == NULL) {
fprintf(stderr, "mysql_real_connect() failed: %s\n", mysql_error(*conn));
mysql_close(*conn);
exit(1);
}
printf("Connected to database successfully!\n");
}
void create_table(MYSQL *conn) {
char *sql = "CREATE TABLE IF NOT EXISTS students ("
"id INT AUTO_INCREMENT PRIMARY KEY,"
"name VARCHAR(50) NOT NULL,"
"score FLOAT)";
if (mysql_query(conn, sql)) {
fprintf(stderr, "CREATE TABLE failed: %s\n", mysql_error(conn));
}
}
void add_student(MYSQL *conn) {
char name[50];
float score;
printf("Enter student name: ");
scanf("%s", name);
printf("Enter student score: ");
scanf("%f", &score);
char sql[200];
sprintf(sql, "INSERT INTO students (name, score) VALUES ('%s', %f)", name, score);
if (mysql_query(conn, sql)) {
fprintf(stderr, "INSERT failed: %s\n", mysql_error(conn));
} else {
printf("Student added successfully!\n");
}
}
void list_students(MYSQL *conn) {
if (mysql_query(conn, "SELECT * FROM students")) {
fprintf(stderr, "SELECT failed: %s\n", mysql_error(conn));
return;
}
MYSQL_RES *result = mysql_store_result(conn);
if (result == NULL) {
fprintf(stderr, "mysql_store_result() failed: %s\n", mysql_error(conn));
return;
}
MYSQL_ROW row;
printf("ID\tName\tScore\n");
while ((row = mysql_fetch_row(result)) != NULL) {
printf("%s\t%s\t%s\n", row[0], row[1], row[2]);
}
mysql_free_result(result);
}
void update_student(MYSQL *conn) {
int id;
float new_score;
printf("Enter student ID to update: ");
scanf("%d", &id);
printf("Enter new score: ");
scanf("%f", &new_score);
char sql[200];
sprintf(sql, "UPDATE students SET score = %f WHERE id = %d", new_score, id);
if (mysql_query(conn, sql)) {
fprintf(stderr, "UPDATE failed: %s\n", mysql_error(conn));
} else {
printf("Student updated successfully!\n");
}
}
void delete_student(MYSQL *conn) {
int id;
printf("Enter student ID to delete: ");
scanf("%d", &id);
char sql[100];
sprintf(sql, "DELETE FROM students WHERE id = %d", id);
if (mysql_query(conn, sql)) {
fprintf(stderr, "DELETE failed: %s\n", mysql_error(conn));
} else {
printf("Student deleted successfully!\n");
}
}
int main() {
MYSQL *conn;
init_db(&conn);
create_table(conn);
int choice;
do {
printf("\nStudent Management System\n");
printf("1. Add Student\n");
printf("2. List Students\n");
printf("3. Update Student\n");
printf("4. Delete Student\n");
printf("0. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1: add_student(conn); break;
case 2: list_students(conn); break;
case 3: update_student(conn); break;
case 4: delete_student(conn); break;
case 0: printf("Exiting...\n"); break;
default: printf("Invalid choice!\n");
}
} while (choice != 0);
mysql_close(conn);
return 0;
}
七、常见问题与解决方案
1. 连接失败:检查MySQL服务是否运行、用户名密码是否正确、防火墙是否阻止连接。
2. 库文件找不到:编译时需指定MySQL库路径(如`gcc program.c -I/usr/local/mysql/include -L/usr/local/mysql/lib -lmysqlclient`)。
3. 中文乱码:在连接后执行`SET NAMES utf8mb4`,确保数据库、表、字段的字符集一致。
4. 内存泄漏:务必在程序结束前调用`mysql_close()`和`mysql_free_result()`。
关键词
C语言、MySQL数据库、连接操作、CRUD操作、MySQL Connector/C、SQL语句执行、结果集处理、错误处理、资源管理
简介
本文通过完整的实例,详细介绍了如何在C语言环境中使用MySQL Connector/C连接MySQL数据库,执行创建表、插入数据、查询数据、更新数据和删除数据等操作。内容涵盖环境准备、连接数据库、执行SQL语句、处理结果集、错误处理与资源管理,并提供了一个学生信息管理系统的完整代码,适合C语言开发者学习数据库编程。