1. libpq 对应驱动包
解压到指定目录,以 解压到/gauss/software/libpq305为例
2.配置连接串
dbname=数据库名 port=端囗号 host='ip1,ip2' user='用户名' password='密码' 参数 1=xxx 参数 2=xxx 参数 3=xxx
示例
conninfo="dbname=postgres port=26000
host='172.198.194.194,172.198.194.195'user='test'
password='startinit123.' application name=testconnect timeout=5 sslmode=allow "
3.编译 libpq 可执行程序
以c程序为例
3.1 编译工具
gcc
3.2 编译方法
gcc -o test libpg-test.c -l /gauss/software/libpq305/include -L /gauss/software/libpq305/lib -lpq
3.3 加参数执行程序
./test
postgres://user:password@ipl:port,ip2:port/dbname?target_sessionattrs=read-write
例:
./test
postgres://test:startinitt123.@172.198.194.194:26000,172.198.194.195:26000/postgres?target session attrs=read-write
或
./test(程序里已经配置好连接串)
注意:字符串开关 postgres 与 postgresql 无差别
注意:用户的密码中如何包含特殊字符,例如!#,需要用反斜杠做转义。因为!#在 linux 中有特殊含义,否则密码不识别。
参数说明:
target_session_attrs=any : libpq 不会刻意去连接主机,而是按照ip 顺序连接
target_session_attrs=read-write: libpq 会自动连接可读写的主库
4. 测试程序
#include
#include
#include "libpq-fe.h"
static void
exit nicely(PGconn *conn)
{
PQfinish(conn);
exit(1);
}
int
main(int argc, char **argv)
{
const char *conninfo;
PGconn *conn;
PGresult *res;
int nFields;
int i,
j;
/*
*如果用户在命令行上提供了一个参数,将它用作连接信息串。
*否则默认用设置 dbname=postgres 并且为所有其他链接参数使用环境变量或默认值。
*/
if (argc > 1)
conninfo = argv[1];
else
conninfo ="dbname=postgres port=26000 host='172.198.194.194,172.198.194.195' application_name=test connect_timeout=5 sslmode=allow user='test' password='startinitt123.'";
/* 建立到数据库的一个连接 */
conn= PQconnectdb(conninfo);
/* 检查看后端连接是否成功建立 */
if (PQstatus(conn)!= CONNECTION OK)
{
fprintf(stderr, "Connection to database failed: %s",
PQerrorMessage(conn));
exit_nicely(conn);
/* 设置总是安全的搜索路径,这样恶意用户就无法取得控制。 */
res = PQexec(conn,
"SELECT pg_catalog.set_config('search_path', ", false)");
if (PQresultStatus(res)!=PGRES_TUPLES_OK)
{
fprintf(stderr, "SET failed: %s",PQerrorMessage(conn));
PQclear(res);
exit nicely(conn);
}
/*
*任何时候不再需要 PGresult 时,应该 PQclear 它来避免内存泄露
*/
PQclear(res);
/*
*创建一个测试表结构
*/
res = PQexec(conn, "CREATE TABLE TEST_LIB(id INT,name VARCHAR)");
if (PQresultStatus(res)!= PGRES_COMMAND_OK)
{
fprintf(stderr, "CREATE TABLE TEST_LIB failed:%s",PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
PQclear(res);
/*
*我们的测试案例这里涉及使用一个游标,对它我们必须用在一个事务块内。
*我们可以在一个单一的"select * from test"的PQexec()中做整个事情,
*但是作为一个好的例子它太琐碎
*/
/*开始一个事务块 */
res = PQexec(conn, "BEGIN");
if (PQresultStatus(res)!= PGRES COMMAND OK)
{
fprintf(stderr, "BEGIN command failed: %s",PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
PQclear(res);
res = PQexec(conn, "INSERT INTO TEST_LIB VALUES(1,'test_username')");
if (PQresultStatus(res)!= PGRES_COMMAND_OK)
{
fprintf(stderr, "INSERT INTO TEST_LIB failed: %s",PQerrorMessage(conn));
PQclear(res);
exit nicely(conn);
}
PQclear(res);
res = PQexec(conn, "INSERT INTO TEST_LIB VALUES(2,'aaaaaaaaaa')");
if (PQresultStatus(res)!= PGRES COMMAND OK)
{
fprintf(stderr, "INSERT INTO TEST_LIB failed: %s",PQerrorMessage(conn));
PQclear(res);
exit nicely(conn);
}
PQclear(res);
res = PQexec(conn, "SELECT * FROM TEST_LIB");
if (PQresultStatus(res)!=PGRES TUPLES OK)
{
fprintf(stderr, "SELECT TABLE TEST_LIB failed: %s", PQerrorMessage(conn));
PQclear(res);
exit nicely(conn);
}
/*首先,打印出属性名 */
nFields = Panfields(res);
for (i=0; i< nFields;i++)
printf("%-15s", PQfname(res, i));
printf("\n\n");
/~接下来,打印出行 */
for (i = 0; i< PQntuples(res); i++)
{
for (j= 0; j< nFields; j++)
printf("%-15s", PQgetvalue(res, i, j));
printf("\n");
}
PQclear(res);
printf("-------------------------------\n");
res = PQexec(conn, "UPDATE TEST_LIB SET name='mike' WHERE id=2");
if (PQresultStatus(res)!= PGRES_COMMAND_OK)
{
fprintf(stderr, "INSERT INTO TEST_LIB failed: %s",PQerrorMessage(conn));
PQclear(res);
exit nicely(conn);
}
PQclear(res);
res = PQexec(conn, "SELECT * FROM TEST_LIB");
if (PQresultStatus(res)!= PGRES_TUPLES_OK)
{
fprintf(stderr, "SELECT TABLE TEST_LIB failed:%s",PQerrorMessage(conn));
PQclear(res);
exit nicely(conn);
}
/*首先,打印出属性名 */
nFields = PQnfields(res);
for (i= 0;i< nFields;i++)
printf("%-15s", PQfname(res, i));
printf("\n\n");
/*接下来,打印出行 */
for (i = 0;i< PQntuples(res); i++)
{
for (j= 0; j< nFields; j++)
printf("%-15s", PQgetvalue(res, i, j));
printf("\n");
}
PQclear(res);
/*删除表以便下回运行,创建表 TEST */
res = PQexec(conn, "DROP TABLE TEST_LIB");
PQclear(res);
/*结束事务 */
res = PQexec(conn, "END");
PQclear(res);
/*关闭到数据库的连接并且清理 */
PQfinish(conn);
return 0;
}