在C语言中连接数据库服务器,本质上是调用数据库官方的C接口库,通过连接函数传入IP、端口、账号、密码完成握手,然后执行SQL语句。 无论你用的是MySQL、PostgreSQL还是SQL Server,思路都一致:先初始化句柄,再连接,最后释放资源,下面以最常见的MySQL为例,拆开每一步给你讲清楚。
c语言连接mysql数据库,离不开这三步准备
很多新手一上来就写代码,结果编译报错一片红,其实在c语言连接mysql数据库之前,先把环境弄干净,后面会省事很多。
选对开发库
- MySQL:官方提供libmysqlclient(也叫MySQL Connector/C),头文件为
mysql.h。 - PostgreSQL:官方提供libpq,头文件为
libpq-fe.h。 - SQL Server:Linux环境用FreeTDS,Windows环境直接用ODBC驱动。
建议从MySQL入手,因为资料最全,遇到问题时更容易搜到答案。
安装开发库命令
Ubuntu/Debian执行:
sudo apt-get install libmysqlclient-dev
CentOS/RHEL执行:
sudo yum install mysql-devel
Windows用户则需要从MySQL官网下载Connector/C的zip包,解压后把include和lib目录配置到Visual Studio或MinGW中。
验证开发库是否装好
终端执行:
pkg-config --modversion mysqlclient
如果有版本号输出,说明库已经就位,没有的话,检查PATH环境变量或安装的包名是否正确。
linux下c语言连接数据库服务器:从初始化到断开
这是最典型的场景,linux下c语言连接数据库服务器,代码写起来不复杂,但每个环节都要照顾到。
初始化连接句柄
#include <mysql.h>
#include <stdio.h>
MYSQL conn;
conn = mysql_init(NULL);
if (conn == NULL) {
fprintf(stderr, "初始化失败n");
return -1;
}
mysql_init负责分配一个MYSQL对象,后续所有操作都围绕它展开。
设置连接超时参数
在连接之前,建议先设置超时,避免网络异常时程序卡住不动:
int timeout = 3; mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);
这段代码表示连接超时上限为3秒,超时立即返回错误,而不是无限等待。
使用mysql_real_connect建立连接
if (mysql_real_connect(conn, "192.168.1.10", "root", "your_password", "test_db", 3306, NULL, 0) == NULL) { fprintf(stderr, "连接失败: %sn", mysql_error(conn)); mysql_close(conn); return -1; }
参数从左到右依次是:主机地址、用户名、密码、数据库名、端口、socket路径、客户端标志,如果数据库在本地,主机地址可以写localhost或0.0.1;如果跨服务器,必须写对IP,并确保服务端允许远程连接。
执行SQL语句并处理结果集
使用mysql_query执行SQL,再用mysql_store_result取出结果:
if (mysql_query(conn, "SELECT id, name FROM users") != 0) {
fprintf(stderr, "查询失败: %sn", mysql_error(conn));
mysql_close(conn);
return -1;
}
MYSQL_RES result = mysql_store_result(conn);
MYSQL_ROW row;
while ((row = mysql_fetch_row(result)) != NULL) {
printf("id=%s, name=%sn", row[0], row[1]);
}
mysql_free_result(result);
注意:mysql_store_result会把所有结果一次性读入内存,数据量巨大时,建议改用mysql_use_result流式读取,防止内存被撑爆。
关闭连接收尾
mysql_close(conn);
所有查询操作结束后,一定要调用这一句释放句柄,否则连接会一直占着服务器资源,在高并发场景下很快就把数据库的连接数打满。
一个完整示例整合
#include <mysql.h>
#include <stdio.h>
int main() {
MYSQL conn = mysql_init(NULL);
if (conn == NULL) return 1;
int timeout = 3;
mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);
if (mysql_real_connect(conn, "192.168.1.10", "root", "123456", "demo", 3306, NULL, 0) == NULL) {
fprintf(stderr, "连接失败: %sn", mysql_error(conn));
return 1;
}
mysql_query(conn, "SET NAMES utf8mb4");
mysql_query(conn, "SELECT FROM staff");
MYSQL_RES res = mysql_store_result(conn);
MYSQL_ROW row;
while ((row = mysql_fetch_row(res)) != NULL) {
printf("%s %sn", row[0], row[1]);
}
mysql_free_result(res);
mysql_close(conn);
return 0;
}
编译命令:
gcc -o demo demo.c -I/usr/include/mysql -lmysqlclient
这里-I指定头文件路径,-lmysqlclient指定链接库,顺序不能乱,否则可能出现”未定义引用”的报错。
不同数据库服务器的C语言连接方式对比
在数据库选型时,你可能会纠结,这里把主流数据库的C接口差异摆出来。
| 数据库 | C接口库 | 头文件 | 连接函数 | 使用建议 |
|---|---|---|---|---|
| MySQL | libmysqlclient | mysql.h | mysql_real_connect | 中小项目、Web后台,上手快 |
| PostgreSQL | libpq | libpq-fe.h | PQconnectdb | 复杂查询、事务要求高的系统 |
| SQL Server | ODBC / FreeTDS | sql.h | SQLDriverConnect | Windows生态、大型企业系统 |
PostgreSQL的写法是:
PGconn conn = PQconnectdb("host=127.0.0.1 port=5432 dbname=test user=postgres password=123456");
SQL Server通过ODBC连接时,需要先设置数据源(DSN),或者直接在连接字符串里写完整描述,步骤稍繁琐,但逻辑与MySQL一致:建立连接、执行SQL、处理结果。
c语言连接数据库连接超时怎么办
c语言连接数据库连接超时是个高频问题,但原因往往不在代码里,而在网络和服务配置上,按下面的顺序排查,基本能定位。
第一步:确认网络能通
在客户端机器执行:
ping 192.168.1.10
ping不通,先查网段、路由、防火墙,跨云厂商时,还要到控制台检查安全组规则是否放通了3306端口。
第二步:确认服务端监听地址
在数据库服务器上执行:
netstat -an | grep 3306
如果看到监听地址是0.0.1:3306,说明MySQL只接受本地连接,需要修改/etc/mysql/my.cnf中的:
bind-address = 0.0.0.0
然后重启MySQL服务。
第三步:用命令行工具排除账户授权问题
mysql -h 192.168.1.10 -P 3306 -u root -p
命令行能连上但C程序超时,说明代码里的host或端口写错了,或者socket参数传了非NULL值,命令行也超时,那就是授权或网络问题。
第四步:检查防火墙
sudo ufw status
有防火墙时,允许3306端口通过:
sudo ufw allow 3306/tcp
行业共识认为,这类问题中相当一部分出在bind-address上,而不是代码本身。
把连接逻辑封装成函数,避免重复造轮子
在真实项目中,你肯定不希望在每个需要数据库的地方都写一遍初始化代码,封装一个通用的连接函数:
MYSQL connect_db(const char host, const char user, const char pass, const char db) {
MYSQL conn = mysql_init(NULL);
if (conn == NULL) return NULL;
int timeout = 3;
mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);
if (mysql_real_connect(conn, host, user, pass, db, 3306, NULL, 0) == NULL) {
fprintf(stderr, "数据库连接失败: %sn", mysql_error(conn));
mysql_close(conn);
return NULL;
}
return conn;
}
调用时只需一行:
MYSQL conn = connect_db("192.168.1.10", "app_user", "secret", "app_db");
连接参数建议放到配置文件里读取,改密码、换机房时不用重新编译代码,再配合一个close_db函数,资源管理就清晰多了。
关于c语言连接数据库服务器的几个高频问题
为什么编译时找不到mysql.h?
没安装开发库,或者头文件路径不在默认搜索范围,先执行find /usr -name mysql.h找到实际位置,然后在编译命令中加-I参数指定目录,如果是CentOS系统,确认安装的是mysql-devel,而不是mysql客户端工具。
执行UPDATE语句后,mysql_store_result返回NULL正常吗?
正常,UPDATE、INSERT、DELETE这类语句不产生结果集,mysql_store_result会返回NULL,此时不应该报错,先检查mysql_field_count(conn)的返回值,如果为0,说明确实没有字段可读取,只有该函数返回值大于0且mysql_store_result仍为NULL时,才代表查询有错。
如何在C语言中安全拼接SQL参数?
不要使用sprintf直接拼接,这会引发SQL注入,C语言连接mysql数据库时,可以用mysql_real_escape_string对参数转义,或者使用预处理语句mysql_stmt_prepare绑定参数,预处理是更稳妥的防御方式,同时也能提升批量执行的效率。
最后说一句
在C语言中连接数据库服务器,核心就是三步:初始化句柄、调用连接函数、执行SQL并释放资源,环境装好,参数写对,超时排查思路清晰,你就能搞定MySQL、PostgreSQL和SQL Server,遇到问题不要闷头改代码,先看网络,再看端口,最后看权限。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/731514.html




