在C语言中连接SQL数据库通常需要使用数据库提供的API(应用程序编程接口)或第三方库,不同数据库(如MySQL、PostgreSQL、SQLite、SQL Server等)有不同的连接方式,以下以常用的MySQL和SQLite为例,详细说明C语言连接SQL数据库的步骤、代码示例及注意事项。
连接MySQL数据库
MySQL提供了C语言的官方连接库libmysqlclient
,以下是详细步骤:
安装开发库
在Linux系统中,使用包管理器安装:
sudo apt-get install libmysqlclient-dev # Debian/Ubuntu sudo yum install mysql-devel # CentOS/RHEL
在Windows系统中,从MySQL官网下载Connector/C并配置开发环境。
包含头文件和链接库
代码中需包含mysql.h
,并在编译时链接mysqlclient
库:
gcc your_program.c -o your_program -lmysqlclient
连接数据库代码示例
#include <mysql/mysql.h> #include <stdio.h> int main() { MYSQL *conn; MYSQL_RES *result; MYSQL_ROW row; // 初始化连接句柄 conn = mysql_init(NULL); if (conn == NULL) { fprintf(stderr, "mysql_init() failedn"); return 1; } // 连接数据库(参数:主机、用户、密码、数据库名、端口、socket、标志) if (mysql_real_connect(conn, "localhost", "username", "password", "database_name", 0, NULL, 0) == NULL) { fprintf(stderr, "mysql_real_connect() failed: %sn", mysql_error(conn)); mysql_close(conn); return 1; } // 执行SQL查询 if (mysql_query(conn, "SELECT * FROM users")) { fprintf(stderr, "mysql_query() failed: %sn", mysql_error(conn)); mysql_close(conn); return 1; } // 获取结果集 result = mysql_store_result(conn); if (result == NULL) { fprintf(stderr, "mysql_store_result() failedn"); mysql_close(conn); return 1; } // 遍历结果集 printf("IDtNametEmailn"); while ((row = mysql_fetch_row(result))) { printf("%st%st%sn", row[0], row[1], row[2]); } // 释放结果集和关闭连接 mysql_free_result(result); mysql_close(conn); return 0; }
关键函数说明
mysql_init()
:初始化连接句柄。mysql_real_connect()
:建立数据库连接,需指定主机、用户名、密码等参数。mysql_query()
:执行SQL语句。mysql_store_result()
:获取查询结果集。mysql_fetch_row()
:逐行读取结果集。mysql_close()
:关闭连接。
连接SQLite数据库
SQLite是一个轻量级嵌入式数据库,无需额外服务,其C语言接口已集成在sqlite3
库中。
安装开发库
Linux系统:
sudo apt-get install libsqlite3-dev # Debian/Ubuntu sudo yum install sqlite-devel # CentOS/RHEL
编译时链接库
gcc your_program.c -o your_program -lsqlite3
连接数据库代码示例
#include <sqlite3.h> #include <stdio.h> int main() { sqlite3 *db; char *errMsg = NULL; int rc; // 打开数据库(如果不存在则创建) rc = sqlite3_open("test.db", &db); if (rc != SQLITE_OK) { fprintf(stderr, "Cannot open database: %sn", sqlite3_errmsg(db)); return 1; } // 执行SQL语句(创建表) const char *sql = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT);"; rc = sqlite3_exec(db, sql, NULL, NULL, &errMsg); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %sn", errMsg); sqlite3_free(errMsg); sqlite3_close(db); return 1; } // 插入数据 sql = "INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');"; rc = sqlite3_exec(db, sql, NULL, NULL, &errMsg); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %sn", errMsg); sqlite3_free(errMsg); } // 查询数据 sql = "SELECT id, name, email FROM users;"; sqlite3_stmt *stmt; rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); if (rc != SQLITE_OK) { fprintf(stderr, "Failed to prepare statement: %sn", sqlite3_errmsg(db)); sqlite3_close(db); return 1; } printf("IDtNametEmailn"); while (sqlite3_step(stmt) == SQLITE_ROW) { printf("%dt%st%sn", sqlite3_column_int(stmt, 0), sqlite3_column_text(stmt, 1), sqlite3_column_text(stmt, 2)); } // 释放资源并关闭数据库 sqlite3_finalize(stmt); sqlite3_close(db); return 0; }
关键函数说明
sqlite3_open()
:打开或创建数据库文件。sqlite3_exec()
:执行无结果集的SQL语句(如CREATE、INSERT)。sqlite3_prepare_v2()
:准备SQL语句,返回sqlite3_stmt
对象。sqlite3_step()
:逐步执行预处理语句。sqlite3_column_*()
:获取列数据(如sqlite3_column_int()
、sqlite3_column_text()
)。sqlite3_finalize()
:释放预处理语句。sqlite3_close()
:关闭数据库连接。
常见数据库连接对比
数据库 | 头文件 | 链接库 | 特点 |
---|---|---|---|
MySQL | <mysql.h> | -lmysqlclient | 需要独立服务,适合大型应用 |
SQLite | <sqlite3.h> | -lsqlite3 | 嵌入式,无需服务,轻量级 |
PostgreSQL | <libpq-fe.h> | -lpq | 功能强大,支持复杂查询 |
SQL Server | <sql.h> | -lsybdb | 微软生态,Windows常用 |
注意事项
- 错误处理:每次调用API后应检查返回值,避免程序因未处理错误而崩溃。
- 资源释放:及时释放结果集、预处理语句等资源,防止内存泄漏。
- 线程安全:MySQL的连接句柄不可跨线程共享,SQLite默认线程不安全(需编译时启用线程安全选项)。
- SQL注入防护:避免直接拼接SQL字符串,使用参数化查询(如MySQL的
mysql_stmt_prepare
)。
相关问答FAQs
Q1: C语言连接MySQL时出现“mysql_real_connect() failed: Can’t connect to MySQL server on ‘localhost’ (10061)”错误,如何解决?
A: 此错误通常表示MySQL服务未启动或连接参数错误,解决方案:
- 确保MySQL服务已运行(Linux下执行
sudo systemctl start mysql
,Windows通过服务管理器启动)。 - 检查主机名、用户名、密码是否正确,确认数据库是否存在。
- 如果使用远程连接,检查防火墙是否放行MySQL默认端口(3306)。
Q2: SQLite数据库文件路径如何指定?能否使用内存数据库?
A: SQLite通过sqlite3_open()
的文件路径参数指定数据库位置:
- 若路径为
"test.db"
,则在当前目录创建或打开文件; - 若路径为
":memory:"
,则创建内存数据库(仅在程序运行时存在,关闭后数据丢失)。
示例:sqlite3_open(":memory:", &db); // 内存数据库 sqlite3_open("/path/to/database.db", &db); // 指定路径
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复