在C语言中连接数据库是许多应用程序开发的核心需求,无论是开发桌面软件、后端服务还是嵌入式系统,都可能需要与数据库交互,本文将详细介绍在C语言中连接数据库的常用方法、步骤及注意事项,帮助开发者快速上手。

选择合适的数据库接口
在C语言中连接数据库,首先需要选择合适的API(应用程序接口),常见的数据库及其C语言接口包括:
- MySQL:使用MySQL C API(libmysqlclient)
- PostgreSQL:使用libpq接口
- SQLite:使用SQLite3 C API
- Oracle:使用OCI(Oracle Call Interface)
- ODBC:通用数据库接口,支持多种数据库
SQLite因其轻量级、无需独立服务器配置,适合小型应用;MySQL和PostgreSQL则更适合中大型项目;ODBC提供了跨数据库的统一接口,适合需要兼容多种数据库的场景。
以MySQL为例:连接数据库的完整流程
以下以MySQL为例,详细说明C语言连接数据库的步骤。
安装开发库
在Linux系统中,可通过包管理器安装MySQL开发库:
sudo apt-get install libmysqlclient-dev # Ubuntu/Debian sudo yum install mysql-devel # CentOS/RHEL
在Windows系统中,需从MySQL官网下载Connector/C并配置开发环境。

包含头文件并链接库
在代码中包含MySQL头文件,并在编译时链接MySQL库:
#include <mysql/mysql.h> // Linux // #include <winsock2.h> // Windows可能需要额外包含
编译命令示例(Linux):
gcc your_program.c -o output -lmysqlclient
初始化连接结构体
使用mysql_init()函数初始化MYSQL结构体:
MYSQL *conn;
conn = mysql_init(NULL);
if (conn == NULL) {
fprintf(stderr, "mysql_init() failed\n");
exit(1);
}
建立数据库连接
通过mysql_real_connect()函数建立连接:
conn = mysql_real_connect(
conn, // MYSQL结构体指针
"localhost", // 服务器地址
"username", // 用户名
"password", // 密码
"database", // 数据库名
0, // 端口号(0表示默认)
NULL, // Unix套接字(Windows设为NULL)
0 // 客户端标志
);
if (conn == NULL) {
fprintf(stderr, "mysql_real_connect() failed: %s\n", mysql_error(conn));
mysql_close(conn);
exit(1);
}
执行SQL语句
使用mysql_query()执行SQL查询:

if (mysql_query(conn, "SELECT * FROM users")) {
fprintf(stderr, "SELECT failed: %s\n", mysql_error(conn));
exit(1);
}
处理查询结果
通过mysql_store_result()获取结果集,并遍历输出:
MYSQL_RES *result = mysql_store_result(conn);
if (result == NULL) {
if (mysql_field_count(conn) == 0) {
printf("No data returned\n");
} else {
fprintf(stderr, "mysql_store_result() failed: %s\n", mysql_error(conn));
exit(1);
}
} else {
MYSQL_ROW row;
MYSQL_FIELD *field;
// 打印列名
while ((field = mysql_fetch_field(result))) {
printf("%-20s", field->name);
}
printf("\n");
// 打印数据
while ((row = mysql_fetch_row(result))) {
for (int i = 0; i < mysql_num_fields(result); i++) {
printf("%-20s", row[i] ? row[i] : "NULL");
}
printf("\n");
}
mysql_free_result(result);
}
关闭连接
操作完成后,关闭连接并释放资源:
mysql_close(conn);
错误处理与最佳实践
- 检查返回值:所有MySQL API函数的返回值都应进行检查,尤其是可能失败的操作。
- 内存管理:及时释放结果集(
mysql_free_result)和连接(mysql_close)。 - SQL注入防护:使用
mysql_real_escape_string()对用户输入进行转义,或使用预处理语句(mysql_stmt_prepare等)。 - 线程安全:MySQL C API默认不是线程安全的,需为每个线程创建独立的
MYSQL结构体。
其他数据库连接简介
SQLite连接示例
#include <sqlite3.h>
sqlite3 *db;
int rc = sqlite3_open("test.db", &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
return 1;
}
// 执行SQL语句...
sqlite3_close(db);
ODBC连接示例
#include <sql.h> #include <sqlext.h> SQLHENV env; SQLHDBC conn; SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); SQLAllocHandle(SQL_HANDLE_DBC, env, &conn); SQLConnect(conn, (SQLCHAR*)"DSN", SQL_NTS, NULL, 0, NULL, 0); // 执行SQL语句... SQLDisconnect(conn); SQLFreeHandle(SQL_HANDLE_DBC, conn); SQLFreeHandle(SQL_HANDLE_ENV, env);
常见问题与解决方案
- 连接超时:检查数据库服务是否运行,网络是否通畅,或调整连接超时参数。
- 字符集问题:通过
mysql_set_character_set(conn, "utf8mb4")设置正确的字符集。
相关问答FAQs
Q1: 如何在C语言中防止SQL注入?
A1: 使用预处理语句(Prepared Statements)是防止SQL注入的最佳方式,以MySQL为例,可通过mysql_stmt_prepare()、mysql_stmt_bind_param()和mysql_stmt_execute()实现参数化查询。
MYSQL_STMT *stmt = mysql_stmt_init(conn);
mysql_stmt_prepare(stmt, "INSERT INTO users (name, age) VALUES (?, ?)", strlen("INSERT INTO users (name, age) VALUES (?, ?)"));
MYSQL_BIND bind[2];
// 绑定参数...
mysql_stmt_execute(stmt);
mysql_stmt_close(stmt);
Q2: 连接数据库时出现“Can't connect to MySQL server on 'localhost'”错误怎么办?
A2: 该错误通常由以下原因导致:
- MySQL服务未启动(需运行
sudo systemctl start mysql); - 用户名或密码错误;
- 权限不足(需使用
GRANT命令授予用户远程访问权限); - 防火墙阻止了3306端口(需开放防火墙规则)。
可通过mysql -u username -p命令手动测试连接,进一步定位问题。