示例

常用功能示例代码

示例1:

  1. /*
  2. * testlibpq.c
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <libpq-fe.h>
  7. static void
  8. exit_nicely(PGconn *conn)
  9. {
  10. PQfinish(conn);
  11. exit(1);
  12. }
  13. int
  14. main(int argc, char **argv)
  15. {
  16. const char *conninfo;
  17. PGconn *conn;
  18. PGresult *res;
  19. int nFields;
  20. int i,j;
  21. /*
  22. * 用户在命令行上提供了conninfo字符串的值时使用该值
  23. * 否则环境变量或者所有其它连接参数
  24. * 都使用缺省值。
  25. */
  26. if (argc > 1)
  27. conninfo = argv[1];
  28. else
  29. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";
  30. /* 连接数据库 */
  31. conn = PQconnectdb(conninfo);
  32. /* 检查后端连接成功建立 */
  33. if (PQstatus(conn) != CONNECTION_OK)
  34. {
  35. fprintf(stderr, "Connection to database failed: %s",
  36. PQerrorMessage(conn));
  37. exit_nicely(conn);
  38. }
  39. /*
  40. * 测试实例涉及游标的使用时候必须使用事务块
  41. *把全部放在一个 "select * from pg_database"
  42. * PQexec() 里,过于简单,不推荐使用
  43. */
  44. /* 开始一个事务块 */
  45. res = PQexec(conn, "BEGIN");
  46. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  47. {
  48. fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
  49. PQclear(res);
  50. exit_nicely(conn);
  51. }
  52. /*
  53. * 在结果不需要的时候PQclear PGresult,以避免内存泄漏
  54. */
  55. PQclear(res);
  56. /*
  57. * 从系统表 pg_database(数据库的系统目录)里抓取数据
  58. */
  59. res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
  60. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  61. {
  62. fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
  63. PQclear(res);
  64. exit_nicely(conn);
  65. }
  66. PQclear(res);
  67. res = PQexec(conn, "FETCH ALL in myportal");
  68. if (PQresultStatus(res) != PGRES_TUPLES_OK)
  69. {
  70. fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
  71. PQclear(res);
  72. exit_nicely(conn);
  73. }
  74. /* 打印属性名称 */
  75. nFields = PQnfields(res);
  76. for (i = 0; i < nFields; i++)
  77. printf("%-15s", PQfname(res, i));
  78. printf("\n\n");
  79. /* 打印行 */
  80. for (i = 0; i < PQntuples(res); i++)
  81. {
  82. for (j = 0; j < nFields; j++)
  83. printf("%-15s", PQgetvalue(res, i, j));
  84. printf("\n");
  85. }
  86. PQclear(res);
  87. /* 关闭入口 ... 不用检查错误 ... */
  88. res = PQexec(conn, "CLOSE myportal");
  89. PQclear(res);
  90. /* 结束事务 */
  91. res = PQexec(conn, "END");
  92. PQclear(res);
  93. /* 关闭数据库连接并清理 */
  94. PQfinish(conn);
  95. return 0;
  96. }

示例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>
  25. /* for ntohl/htonl */
  26. #include <netinet/in.h>
  27. #include <arpa/inet.h>
  28. static void
  29. exit_nicely(PGconn *conn)
  30. {
  31. PQfinish(conn);
  32. exit(1);
  33. }
  34. /*
  35. * 这个函数打印查询结果,这些结果是二进制格式,从上面的
  36. * 注释里面创建的表中抓取出来的
  37. */
  38. static void
  39. show_binary_results(PGresult *res)
  40. {
  41. int i;
  42. int i_fnum,
  43. t_fnum;
  44. /* 使用 PQfnumber 来避免对结果中的字段顺序进行假设 */
  45. i_fnum = PQfnumber(res, "i");
  46. t_fnum = PQfnumber(res, "t");
  47. for (i = 0; i < PQntuples(res); i++)
  48. {
  49. char *iptr;
  50. char *tptr;
  51. int ival;
  52. /* 获取字段值(忽略可能为空的可能) */
  53. iptr = PQgetvalue(res, i, i_fnum);
  54. tptr = PQgetvalue(res, i, t_fnum);
  55. /*
  56. * INT4 的二进制表现形式是网络字节序
  57. * 建议转换成本地字节序
  58. */
  59. ival = ntohl(*((uint32_t *) iptr));
  60. /*
  61. * TEXT 的二进制表现形式是文本,因此libpq能够给它附加一个字节零
  62. * 把它看做 C 字符串
  63. *
  64. */
  65. printf("tuple %d: got\n", i);
  66. printf(" i = (%d bytes) %d\n",
  67. PQgetlength(res, i, i_fnum), ival);
  68. printf(" t = (%d bytes) '%s'\n",
  69. PQgetlength(res, i, t_fnum), tptr);
  70. printf("\n\n");
  71. }
  72. }
  73. int
  74. main(int argc, char **argv)
  75. {
  76. const char *conninfo;
  77. PGconn *conn;
  78. PGresult *res;
  79. const char *paramValues[1];
  80. int paramLengths[1];
  81. int paramFormats[1];
  82. uint32_t binaryIntVal;
  83. /*
  84. * 如果用户在命令行上提供了参数,
  85. * 那么使用该值为conninfo 字符串;否则
  86. * 使用环境变量或者缺省值。
  87. */
  88. if (argc > 1)
  89. conninfo = argv[1];
  90. else
  91. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";
  92. /* 和数据库建立连接 */
  93. conn = PQconnectdb(conninfo);
  94. /* 检查与服务器的连接是否成功建立 */
  95. if (PQstatus(conn) != CONNECTION_OK)
  96. {
  97. fprintf(stderr, "Connection to database failed: %s",
  98. PQerrorMessage(conn));
  99. exit_nicely(conn);
  100. }
  101. /* 把整数值 "2" 转换成网络字节序 */
  102. binaryIntVal = htonl((uint32_t) 2);
  103. /* 为 PQexecParams 设置参数数组 */
  104. paramValues[0] = (char *) &binaryIntVal;
  105. paramLengths[0] = sizeof(binaryIntVal);
  106. paramFormats[0] = 1; /* 二进制 */
  107. res = PQexecParams(conn,
  108. "SELECT * FROM test1 WHERE i = $1::int4",
  109. 1, /* 一个参数 */
  110. NULL, /* 让后端推导参数类型 */
  111. paramValues,
  112. paramLengths,
  113. paramFormats,
  114. 1); /* 要求二进制结果 */
  115. if (PQresultStatus(res) != PGRES_TUPLES_OK)
  116. {
  117. fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
  118. PQclear(res);
  119. exit_nicely(conn);
  120. }
  121. show_binary_results(res);
  122. PQclear(res);
  123. /* 关闭与数据库的连接并清理 */
  124. PQfinish(conn);
  125. return 0;
  126. }