Uma das utilidades de se usar um cursor pela libpq é obter informações sobre as colunas retornadas pelo cursor. Podemos saber tanto o tamanho da coluna quanto o nome da coluna. Para isso, precisamos conhecer três novas funções, que são:
PQnfields
Esta função nos permite saber quantas colunas foram retornadas na query passada ao cursor. O protótipo desta função é:
int PQnfields(const PGresult *res);
PQfname
Esta função nos permite saber o nome de uma determinada coluna, associada ao field_num, aonde a primeira coluna começa no zero. O protótipo desta função é:
char *PQfname(const PGresult *res, int field_num);
PQfsize
Esta função nos permite ter uma idéia do tamanho do campo. Não temos como saber precisamente pois esta função retorna o tamanho em bytes usado internamente pelo PostgreSQL e mesmo assim, para tipos de dados variáveis como VARCHAR esta função retorna -1. O protótipo desta função é:
int PQfsize(const PGresult *res, int field_num);
Uma boa idéia é sempre especificar pelo nome a coluna que você precisa acessar, evitando que quando novas colunas forem acrescentadas o seu programa se perca na quantidade de campos. Para descobrir o índice de um campo através do nome da coluna, podemos usar a função PQfnumber, que tem o seguinte protótipo:
int PQfnumber(const PGresult *res, const char *field_name);
Esta função retorna -1 quando o nome passado como parâmetro não é reconhecido como nome de coluna.
Conhecidas estas funções, é hora de colocar a teoria em prática. Vamos ver como fica o nosso código. Primeiro, vamos criar uma função que irá mostrar as informações sobre as colunas:
void Mostra_Info_Colunas(PGresult *result)
{
int numero_colunas;
int i;
if(!result)
return;
/*Obtém o número de colunas*/
numero_colunas = PQnfields(result);
printf("O conjunto de dados tem %d colunas
", numero_colunas);
for(i = 0; i <numero_colunas; i++)
{
printf("Campo: %d.
Nome: %s
Tamanho Interno: %d
", i, PQfname(result, i), PQfsize(result, i));
}
}
Depois, a nossa função main vai ficar assim:
comando_ok = ExecutaComando("BEGIN WORK", &result);
if(comando_ok)
{
PQclear(result);
/*Executa o comando*/
comando_ok = ExecutaComando("DECLARE curr CURSOR FOR SELECT * FROM contatos", &result);
if(comando_ok)
{
PQclear(result);
comando_ok = ExecutaComando("FETCH 1 IN curr", &result);
if(comando_ok)
Mostra_Info_Colunas(result);
while(comando_ok && PQntuples(result) > 0)
{
PQclear(result);
ExecutaComando("FETCH NEXT IN curr", &result);
}
}
comando_ok = ExecutaComando("COMMIT WORK", &result);
}
if(comando_ok)
PQclear(result);
A saída deve ficar assim (estamos mostrando somente a saída para a função Mostra_Info_Colunas):
O conjunto de dados tem 2 colunas
Campo: 0.
Nome: email
Tamanho Interno: -1
Campo: 1.
Nome: nome
Tamanho Interno: -1