位置: 文档库 > 数据库 > C语言访问MySQL数据库简单实例

C语言访问MySQL数据库简单实例

VortexRift 上传于 2021-05-13 10:55

《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语言开发者学习数据库编程。