Acessando PostgreSQL com C - Cursores

Veremos neste artigo como trabalhar com cursores através da libpq, utilizando a linguagem C.

[ Hits: 42.810 ]

Por: Poleto em 27/04/2006


Informações sobre colunas



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

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Uma breve explicação sobre cursores
   3. Declaração de cursores
   4. Retornando uma linha por vez
   5. Informações sobre colunas
   6. Acessando os dados recuperados
Outros artigos deste autor

Instalando o CMS Drupal 4.7

PostgreSQL - Embutindo comandos SQL no seu código C

Acessando PostgreSQL com C

Leitura recomendada

Ensaio acerca de bibliotecas de código aberto para abstração de acesso a banco de dados em linguagem C++

Acessando PostgreSQL com C

Usando MySQL na linguagem C

PostgreSQL - Embutindo comandos SQL no seu código C

Embutindo um banco de dados SQLite em sua aplicação C++

  
Comentários
[1] Comentário enviado por jragomes em 28/04/2006 - 14:02h

Parabéns pelo artigo, muito bem escrito e detalhado.

[2] Comentário enviado por madsonbraz em 02/05/2006 - 08:53h

Me tire uma duvida, é possivel criar um cluster com o postgresql?

[3] Comentário enviado por poleto em 02/05/2006 - 14:54h

madsonbraz,

E possivel sim, mas eu particularmente nao sei como.

[]'s
Poleto

[4] Comentário enviado por rjesus em 13/03/2007 - 11:20h

Olá, sou novo no linux, utilizoo o SUSE versão 10.1, tentei executar o exemplo que foi passado acima e obtive o seguinte resultado :
suse:/usr/include/pgsql # gcc $(pkg-config --libs --cflags gtk+-2.0) -g teste1.c
/tmp/ccc0dzwL.o: In function `main':
/usr/include/pgsql/teste1.c:13: undefined reference to `PQconnectdb'
/usr/include/pgsql/teste1.c:15: undefined reference to `PQstatus'
/usr/include/pgsql/teste1.c:28: undefined reference to `PQexec'
/usr/include/pgsql/teste1.c:21: undefined reference to `PQerrorMessage'
/usr/include/pgsql/teste1.c:22: undefined reference to `PQfinish'
/usr/include/pgsql/teste1.c:36: undefined reference to `PQresultStatus'
/usr/include/pgsql/teste1.c:42: undefined reference to `PQresultErrorMessage'
/usr/include/pgsql/teste1.c:45: undefined reference to `PQcmdTuples'
/usr/include/pgsql/teste1.c:53: undefined reference to `PQclear'
/usr/include/pgsql/teste1.c:59: undefined reference to `PQfinish'
collect2: ld returned 1 exit status
Alguêm poderia me ajudar ???
Obigado!

[5] Comentário enviado por poleto em 13/03/2007 - 15:04h

Fala rjesus,

Parece que você esqueceu alguns parâmetros para o gcc na hora de executar.
Dá uma olhada neste artigo que tem os detalhes necessários para compilar programas com suporte ao PostgreSQL:

http://www.vivaolinux.com.br/artigos/verArtigo.php?codigo=4169

Qualquer coisa grita.
[]'s
Poleto

[6] Comentário enviado por evaldobarbosa em 04/12/2008 - 15:36h

Eu resolvi o problema criando um arquivo que já automatiza esse negócio pra mim, saca só:

#!/bin/bash

rm cursores

g++ -o arquivo -I/usr/include/postgresql/ arquivo.cpp -lpq
#clear
echo ###### executando #####
if [ -x cursores ] ; then
./cursores
fi

exit 0


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts