更新时间:2024-11-12 GMT+08:00
数据库建连、执行SQL并返回结果
gcc编译libpq源程序,需要通过-I directory选项,提供头文件的安装位置(有些时候编译器会查找缺省的目录,因此可以忽略这些选项)。如:
gcc -I (头文件所在目录) -L (libpq库所在目录) -o testlibpq testlibpq.c -lpq
执行命令为:
./testlibpq.c
如果要使用制作文件(makefile),向CPPFLAGS、LDFLAGS、LIBS变量中增加如下选项:
CPPFLAGS += -I (头文件所在目录) LDFLAGS += -L (libpq库所在目录) LIBS += -lpq 例如: CPPFLAGS += -I$(GAUSSHOME)/include/libpq LDFLAGS += -L$(GAUSSHOME)/lib
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
/* * testlibpq.c * 说明: testlibpq.c源程序,提供libpq基本且常见的使用场景。 * 使用libpq提供的PQconnectdb、PQexec、PQntuples、PQfinish等接口实现数据库建连,执行sql,获取返回结果以及资源清理。 */ #include <stdio.h> #include <stdlib.h> #include <libpq-fe.h> #include <string.h> static void exit_nicely(PGconn *conn) { PQfinish(conn); exit(1); } int main(int argc, char **argv) { /* 此处user、passwd等变量应从环境变量或配置文件读取,环境变量需用户自己按需配置;非环境变量情况下可直接赋值字符串 */ const char conninfo[1024]; PGconn *conn; PGresult *res; int nFields; int i,j; char *passwd = getenv("EXAMPLE_PASSWD_ENV"); char *port = getenv("EXAMPLE_PORT_ENV"); char *host = getenv("EXAMPLE_HOST_ENV"); char *username = getenv("EXAMPLE_USERNAME_ENV"); char *dbname = getenv("EXAMPLE_DBNAME_ENV"); /* * 用户在命令行上提供了conninfo字符串的值时使用该值 * 否则环境变量或者所有其它连接参数 * 都使用缺省值。 */ if (argc > 1) strcpy(conninfo, argv[1]); else sprintf(conninfo, "dbname=%s port=%s host=%s application_name=test connect_timeout=5 sslmode=allow user=%s password=%s", dbname, port, host, username, passwd); /* 连接数据库 */ conn = PQconnectdb(conninfo); /* 检查后端连接成功建立 */ if (PQstatus(conn) != CONNECTION_OK) { fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn)); exit_nicely(conn); } /* * 连接成功后 * 测试实例涉及游标的使用时候必须使用事务块 * 把全部放在一个 "select * from pg_database" * 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 PGresult,以避免内存泄漏 */ PQclear(res); /* * 从系统表 pg_database(数据库的系统目录)里抓取数据 */ res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database"); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn)); PQclear(res); exit_nicely(conn); } PQclear(res); res = PQexec(conn, "FETCH ALL in myportal"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "FETCH ALL 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); /* 关闭入口 ... 不用检查错误 ... */ res = PQexec(conn, "CLOSE myportal"); PQclear(res); /* 结束事务 */ res = PQexec(conn, "END"); PQclear(res); /* 关闭数据库连接并清理 */ PQfinish(conn); return 0; } |
示例运行结果如下,其中“user_name”表示数据库管理员用户名,根据具体使用环境会发生变化:
datname datdba encoding datcollate datctype datistemplate datallowconn datconnlimit datlastsysoid datfrozenxid dattablespace datcompatibilitydatacl datfrozenxid64 datminmxid dattimezone dattype template_pdb 10 7 en_US.UTF-8 en_US.UTF-8 t t -1 12837 0 1663 A 3 2 PRC P templatea 10 7 en_US.UTF-8 en_US.UTF-8 t f -1 12837 0 1663 A {=c/user_name,user_name=CTc/user_name}41372 2 PRC D template1 10 7 en_US.UTF-8 en_US.UTF-8 t t -1 12837 0 1663 A {=c/user_name,user_name=CTc/user_name}40414 2 PRC D templatem 10 7 en_US.UTF-8 en_US.UTF-8 t t -1 12837 0 1663 M {=c/user_name,user_name=CTc/user_name}55146 2 PRC D template0 10 7 en_US.UTF-8 en_US.UTF-8 t f -1 12837 0 1663 A {=c/user_name,user_name=CTc/user_name}39935 2 PRC D postgres 10 7 en_US.UTF-8 en_US.UTF-8 f t -1 12837 0 1663 A 40893 2 PRC D
父主题: 典型应用开发示例