首先安装libpq库,编译时链接-lpq。然后用PQconnectdb连接数据库。示例代码:
#include <libpq-fe.h>
void main() {
const char *conninfo = "dbname=mydb user=myuser password=mypass host=localhost port=5432";
PGconn *conn = PQconnectdb(conninfo);
if (PQstatus(conn) == CONNECTION_BAD) {
fprintf(stderr, "连接失败: %s", PQerrorMessage(conn));
PQfinish(conn);
exit(1);
}
printf("连接成功!");
PQfinish(conn);
}
实用技巧一:错误处理
总是检查PQstatus(conn) != CONNECTION_OK,并用PQerrorMessage获取详细错误信息。执行查询后检查PQresultStatus(res) == PGRES_TUPLES_OK,避免程序崩溃。
查询数据示例
PGresult *res = PQexec(conn, "SELECT id, name FROM users");
if (PQresultStatus(res) == PGRES_TUPLES_OK) {
int rows = PQntuples(res);
for (int i = 0; i < rows; i++) {
printf("%s: %s\n", PQgetvalue(res, i, 0), PQgetvalue(res, i, 1));
}
}
PQclear(res);
插入数据技巧
用PQexecParams防SQL注入:
const char *paramValues[1] = {"newuser"};
int paramLengths[1] = {6};
int paramFormats[1] = {0};
PGresult *res = PQexecParams(conn, "INSERT INTO users(name) VALUES($1)", 1, NULL, paramValues, paramLengths, paramFormats, 0);
事务处理
开始事务:PQexec(conn, "BEGIN"); 提交:PQexec(conn, "COMMIT"); 回滚:PQexec(conn, "ROLLBACK"); 记得在finally块关闭连接PQfinish(conn);
连接池技巧
频繁连接耗资源,自建简单连接池:用数组存多个PGconn,忙时复用空闲连接。或者用libpq的PQconnectStart非阻塞连接。
大对象处理
存文件:lo_open, lo_write, lo_close。示例:Oid oid = lo_creat(conn, INV_READ | INV_WRITE); int fd = lo_open(conn, oid, INV_WRITE); lo_write(conn, fd, buffer, size);
FAQ
Q: 编译时怎么链接libpq?
A: gcc main.c -lpq -I/usr/include/postgresql
Q: 连接超时怎么设置?
A: conninfo加"connect_timeout=10"
Q: 如何处理中文字符?
A: 设置客户端编码PQexec(conn, "SET client_encoding TO 'UTF8'");
Q: 多线程安全吗?
A: libpq线程安全,但每个线程用独立连接。