Я создаю приложение, используя libpq
, и в документации не очень понятно выполнение вызовов процедур и функций в базе данных PostgreSQL. Мне удалось получить возвращаемое значение вызова функции с помощью результата libpq
, но я не знаю, как получить значение выходного параметра, который специально не возвращается функцией или процедурой. Есть ли способ сделать это, и если да, то как?
На уровне SQL параметры OUT выглядят как «передача по ссылке». Однако в libpq выходные параметры и результаты запроса возвращаются одинаково. Успешный вызов процедуры с параметрами OUT установит PGRES_TUPLES_OK и вернет одну строку, содержащую значения выходных параметров.
Вот простой пример, основанный на коде из документации libpq
Сначала создайте процедуру для тестирования:
CREATE PROCEDURE inc_int(INOUT a integer)
LANGUAGE plpgsql
AS $$
BEGIN
a := a+1;
END;
$$;
Затем минимальная программа на C для вызова этой процедуры:
#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"
static void
exit_nicely(PGconn *conn)
{
PQfinish(conn);
exit(1);
}
int
main(int argc, char **argv)
{
const char *conninfo;
PGconn *conn;
PGresult *res;
int nFields;
int i,
j;
conninfo = "dbname = postgres";
/* 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, "%s", PQerrorMessage(conn));
exit_nicely(conn);
}
/* execute the call to our procedure */
res = PQexec(conn, " CALL inc_int(1) ");
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "CALL procedure failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
/* iterate over the resultset - although in this special case
calling PQgetvalue(res, 0, 0) would do */
/* first, print out the attribute names */
nFields = PQnfields(res);
for (i = 0; i < nFields; i++)
printf("%-15s", PQfname(res, i));
printf("\n\n");
/* next, print out the rows */
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;
}
запуск полученной программы:
./pgtest
a
2
Итак, прав ли я, полагая, что для процедуры с выходными параметрами они возвращаются как один кортеж и должны обрабатываться так же, как я бы обрабатывал, например. результат SELECT?
Да, параметры OUT аналогичны параметрам RETURNS в определении функции.
Круто, это была та информация, которой мне не хватало. Не уверен, есть ли это где-нибудь в документации, но мне было недостаточно очевидно, чтобы его найти!
Пожалуйста, отредактируйте свой вопрос и добавьте больше деталей или покажите минимально воспроизводимый пример, насколько это возможно. Покажите хотя бы конкретный пример функции, которую вы хотите использовать, и объясните, с чем именно у вас проблемы.