示例

常用功能示例代码

示例1:

1. /*
2. * testlibpq.c
3. */
4. #include <stdio.h>
5. #include <stdlib.h>
6. #include <libpq-fe.h>

8. static void
9. exit_nicely(PGconn *conn)
10. {
11. PQfinish(conn);
12. exit(1);
13. }

15. int
16. main(int argc, char **argv)
17. {
18. const char *conninfo;
19. PGconn     *conn;
20. PGresult   *res;
21. int         nFields;
22. int         i,j;

24. /*
25. * 用户在命令行上提供了conninfo字符串的值时使用该值
26. * 否则环境变量或者所有其它连接参数
27. * 都使用缺省值。
28. */
29. if (argc > 1)
30. conninfo = argv[1];
31. else
32. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";

34. /* 连接数据库 */
35. conn = PQconnectdb(conninfo);

37. /* 检查后端连接成功建立 */
38. if (PQstatus(conn) != CONNECTION_OK)
39. {
40. fprintf(stderr, "Connection to database failed: %s",
41. PQerrorMessage(conn));
42. exit_nicely(conn);
43. }

45. /*
46. * 测试实例涉及游标的使用时候必须使用事务块
47. *把全部放在一个  "select * from pg_database"
48. * PQexec() 里,过于简单,不推荐使用
49. */

51. /* 开始一个事务块 */
52. res = PQexec(conn, "BEGIN");
53. if (PQresultStatus(res) != PGRES_COMMAND_OK)
54. {
55. fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
56. PQclear(res);
57. exit_nicely(conn);
58. }

60. /*
61. * 在结果不需要的时候PQclear PGresult,以避免内存泄漏
62. */
63. PQclear(res);

65. /*
66. * 从系统表 pg_database(数据库的系统目录)里抓取数据
67. */
68. res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
69. if (PQresultStatus(res) != PGRES_COMMAND_OK)
70. {
71. fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
72. PQclear(res);
73. exit_nicely(conn);
74. }
75. PQclear(res);

77. res = PQexec(conn, "FETCH ALL in myportal");
78. if (PQresultStatus(res) != PGRES_TUPLES_OK)
79. {
80. fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
81. PQclear(res);
82. exit_nicely(conn);
83. }

85. /* 打印属性名称 */
86. nFields = PQnfields(res);
87. for (i = 0; i < nFields; i++)
88. printf("%-15s", PQfname(res, i));
89. printf("\n\n");

91. /* 打印行 */
92. for (i = 0; i < PQntuples(res); i++)
93. {
94. for (j = 0; j < nFields; j++)
95. printf("%-15s", PQgetvalue(res, i, j));
96. printf("\n");
97. }

99. PQclear(res);

101. /* 关闭入口 ... 不用检查错误 ... */
102. res = PQexec(conn, "CLOSE myportal");
103. PQclear(res);

105. /* 结束事务 */
106. res = PQexec(conn, "END");
107. PQclear(res);

109. /* 关闭数据库连接并清理 */
110. PQfinish(conn);

112. return 0;
113. }

示例2:

1. /*
2. * testlibpq2.c
3. *      测试外联参数和二进制I/O。
4. *
5. * 在运行这个例子之前,用下面的命令填充一个数据库
6. *
7. *
8. * CREATE TABLE test1 (i int4, t text);
9. *
10. * INSERT INTO test1 values (2, 'ho there');
11. *
12. * 期望的输出如下
13. *
14. *
15. * tuple 0: got
16. *  i = (4 bytes) 2
17. *  t = (8 bytes) 'ho there'
18. *
19. */
20. #include <stdio.h>
21. #include <stdlib.h>
22. #include <string.h>
23. #include <sys/types.h>
24. #include <libpq-fe.h>

26. /* for ntohl/htonl */
27. #include <netinet/in.h>
28. #include <arpa/inet.h>

30. static void
31. exit_nicely(PGconn *conn)
32. {
33. PQfinish(conn);
34. exit(1);
35. }

37. /*
38. * 这个函数打印查询结果,这些结果是二进制格式,从上面的
39. * 注释里面创建的表中抓取出来的
40. */
41. static void
42. show_binary_results(PGresult *res)
43. {
44. int         i;
45. int         i_fnum,
46. t_fnum;

48. /* 使用 PQfnumber 来避免对结果中的字段顺序进行假设 */
49. i_fnum = PQfnumber(res, "i");
50. t_fnum = PQfnumber(res, "t");

52. for (i = 0; i < PQntuples(res); i++)
53. {
54. char       *iptr;
55. char       *tptr;
56. int         ival;

58. /* 获取字段值(忽略可能为空的可能) */
59. iptr = PQgetvalue(res, i, i_fnum);
60. tptr = PQgetvalue(res, i, t_fnum);

62. /*
63. * INT4 的二进制表现形式是网络字节序
64. * 建议转换成本地字节序
65. */
66. ival = ntohl(*((uint32_t *) iptr));

68. /*
69. * TEXT 的二进制表现形式是文本,因此libpq能够给它附加一个字节零
70. * 把它看做 C 字符串
71. *
72. */

74. printf("tuple %d: got\n", i);
75. printf(" i = (%d bytes) %d\n",
76. PQgetlength(res, i, i_fnum), ival);
77. printf(" t = (%d bytes) '%s'\n",
78. PQgetlength(res, i, t_fnum), tptr);
79. printf("\n\n");
80. }
81. }

83. int
84. main(int argc, char **argv)
85. {
86. const char *conninfo;
87. PGconn     *conn;
88. PGresult   *res;
89. const char *paramValues[1];
90. int         paramLengths[1];
91. int         paramFormats[1];
92. uint32_t    binaryIntVal;

94. /*
95. * 如果用户在命令行上提供了参数,
96. * 那么使用该值为conninfo 字符串;否则
97. * 使用环境变量或者缺省值。
98. */
99. if (argc > 1)
100. conninfo = argv[1];
101. else
102. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";

104. /* 和数据库建立连接 */
105. conn = PQconnectdb(conninfo);

107. /* 检查与服务器的连接是否成功建立 */
108. if (PQstatus(conn) != CONNECTION_OK)
109. {
110. fprintf(stderr, "Connection to database failed: %s",
111. PQerrorMessage(conn));
112. exit_nicely(conn);
113. }

115. /* 把整数值 "2" 转换成网络字节序 */
116. binaryIntVal = htonl((uint32_t) 2);

118. /* 为 PQexecParams 设置参数数组 */
119. paramValues[0] = (char *) &binaryIntVal;
120. paramLengths[0] = sizeof(binaryIntVal);
121. paramFormats[0] = 1;        /* 二进制 */

123. res = PQexecParams(conn,
124. "SELECT * FROM test1 WHERE i = $1::int4",
125. 1,       /* 一个参数 */
126. NULL,    /* 让后端推导参数类型 */
127. paramValues,
128. paramLengths,
129. paramFormats,
130. 1);      /* 要求二进制结果 */

132. if (PQresultStatus(res) != PGRES_TUPLES_OK)
133. {
134. fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
135. PQclear(res);
136. exit_nicely(conn);
137. }

139. show_binary_results(res);

141. PQclear(res);

143. /* 关闭与数据库的连接并清理 */
144. PQfinish(conn);

146. return 0;
147. }