示例

    示例2:

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