Agora que já vimos bastante teoria, é hora de colocar tudo isso
em prática. Vale ressaltar que não entraremos em detalhes sobre
como conectar com o
PostgreSQL ou sobre como executar comandos
pela
libpq, uma vez que existe um artigo aqui sobre este assunto:
O primeiro passo é a declaração do cursor, que em código SQL, tem a seguinte sintaxe:
DECLARE nome_do_cursor CURSOR FOR comando_select
Isso cria e automaticamente abre um cursor que tem o nome especificado em nome_do_cursor. O cursor fica então vinculado ao comando de select SQL que foi especificado em comando_select. Para codificar o nosso programa, vamos declarar uma variável que irá conter o resultado do comando PQexec (e claro, consideramos que já existe uma conexão aberta com o banco, aqui chamada de conn):
/*Ponteiro de resultado*/
PGresult *result;
e a nossa chamada a função PQexec irá ficar assim:
result = PQexec(conn, "DECLARE curr CURSOR FOR SELECT * FROM contatos");
Até aqui, a única novidade é a declaração do cursor. Vale observar que operações com cursores devem sempre estar entre blocos de transações (assunto grande para ser tratado aqui, nos limitaremos a listar os comandos apenas).
Após a declaração do cursor, iremos recuperar os dados retornados (se algum). Esta operação tem o nome de FETCH, e tem a seguinte sintaxe em SQL:
FETCH [FORWARD|BACKWARD] [number|ALL|NEXT] [IN nome_do_cursor];
Onde:
FORWARD e BACKWARD indicam a direção que o cursor irá ler os dados, para frente e para trás, respectivamente. O padrão é FORWARD e normalmente é omitido;
number, ALL e NEXT indicam quantas linhas iremos recuperar: number deve ser trocado por um número qualquer (10, por exemplo, que indica que 10 linhas serão lidas por vez no cursor). ALL recupera todos os dados e NEXT movimenta o cursor fazendo-o apontar para a próxima linha.
IN indica o cursor em que daremos o fetch.
No nosso caso, podemos declarar o fetch da seguinte forma:
result = PQexec(conn, "FETCH ALL IN curr");
Agora que já temos material o suficiente para criar um cursor e dar um fetch, vamos ver como fica o nosso programa. Omitimos o ponto onde fazemos a conexão com o banco de dados.
result = PQexec(conn, "BEGIN WORK");
/*Executa o comando*/
result = PQexec(conn, "DECLARE curr CURSOR FOR SELECT * FROM contatos");
if(!result)
{
printf("Erro executando comando.
");
}
else
{
PQclear(result);
result = PQexec(conn, "FETCH ALL IN curr");
switch(PQresultStatus(result))
{
case PGRES_EMPTY_QUERY:
printf("Nada aconteceu.
");
break;
case PGRES_TUPLES_OK:
printf("A query retornou %d linhas.
", PQntuples(result));
break;
case PGRES_FATAL_ERROR:
printf("Error in query: %s
", PQresultErrorMessage(result));
break;
case PGRES_COMMAND_OK:
printf("%s linhas afetadas.
", PQcmdTuples(result));
break;
default:
printf("Algum outro resultado ocorreu.
");
break;
}
result = PQexec(conn, "COMMIT WORK");
/*Libera o nosso objeto de resultado*/
PQclear(result);
}
Algumas observações sobre o código acima: os comandos 'BEGIN WORK' e 'COMMIT WORK' iniciam e finalizam uma transação, respectivamente. O programa acima irá apenas imprimir na tela a quantidade de linhas que foram retornadas pelo comando select.