一、libpq和存储过程
libpq是应用程序员使用PostgreSQL的C接口。libpq是一个库函数的集合,它们允许客户端
程序传递查询给PostgreSQL后端服务器并且接收这些查询的结果。
存储过程是SQL 语句和可选控制流语句的预编译集合,以一个名称存储并作为一个单元处理。程序头部声明用procedure,程序头部声明时不需要描述返回类型,可以使用in/out/in out三种模式的参数,可以作为一个独立的PL/SQL语句来执行,SQL语句(DML或SELECT)中不可调用存储过程。
二、使用步骤
1.使用libpq库调用存储过程并打印结果
代码如下:
#ifdef WIN32
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include "libpq-fe.h"
/* for ntohl/htonl */
#include <netinet/in.h>
#include <arpa/inet.h>
static void
exit_nicely(PGconn *conn)
{
PQfinish(conn);
exit(1);
}
int
main(int argc, char **argv)
{
const char *conninfo;
PGconn *conn;
PGresult *res;
const char *paramValues[3];
int paramLengths[3];
int paramFormats[3];
uint32_t binaryIntVal;
uint64_t bigbinaryIntVal;
int nFields;
int i,
j;
if (argc > 1)
conninfo = argv[1];
else
conninfo = "dbname = test";
/* Make a connection to the database */
conn = PQconnectdb(conninfo);
/* Check to see that the backend connection was successfully made */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s",
PQerrorMessage(conn));
exit_nicely(conn);
}
/* Convert integer value "2" to network byte order */
binaryIntVal = htonl((uint32_t) 2);
bigbinaryIntVal = htonl((uint64_t) 2);
/* Set up parameter arrays for PQexecParams */
paramValues[0] = (char *) &bigbinaryIntVal;
paramLengths[0] = sizeof(bigbinaryIntVal);
paramFormats[0] = 1; /* binary */
paramValues[1] = "2";
paramLengths[1] = 1;
paramFormats[1] = 0; /* test */
paramValues[2] = (char *) &binaryIntVal;
paramLengths[2] = sizeof(binaryIntVal);
paramFormats[2] = 1; /* binary */
res = PQexecParams(conn,
"call proce_inouttest($1,$2,$3)",
3, /* one param */
NULL, /* let the backend deduce param type */
paramValues,
paramLengths,
paramFormats,
0); /* ask for text results */
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "SELECT 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");
/* next, print out the instances */
for (i = 0; i < PQntuples(res); i++)
{
for (j = 0; j < nFields; j++)
printf("%-15s", PQgetvalue(res, i, j));
printf("\n");
}
PQclear(res);
/* close the connection to the database and cleanup */
PQfinish(conn);
return 0;
}
2.存储过程定义
代码如下:
create or replace procedure proce_inouttest(in nD1 bigint, inout szD varchar, out nD2 integer)
as
$$
begin
nD1:=99;
szD:='qaz';
nD2:=88;
end;
$$
language plpgsql;
3、输出结果
szd nd2
qaz 88
总结
libpq对于存储过程out/inout参数返回值的处理,与一般的select查询返回值处理一样,使用PQnfields、PQntuples、PQgetvalue等函数对结果PGresult结构体进行处理。