29.14. Exemplos

Nota: Seção escrita pelo tradutor, não fazendo parte do manual original.

Esta seção contém exemplos de programas com SQL incorporado à linguagem C. Para ser possível pré-compilar, compilar, gerar o executável e executar estes programas, foi feita a construção da árvore de fontes sob o diretório raiz do usuário (~), conforme mostrado abaixo. O arquivo de fontes postgresql-8.0.0.tar.gz foi baixado no diretório /download. Deve ser notado que não foi feita a instalação, somente foi feita a construção.

cd ~
tar xzvf /download/postgresql-8.0.0.tar.gz
cd postgresql-8.0.0/
./configure
make
All of PostgreSQL successfully made. Ready to install.

Exemplo 29-1. Ler e mostrar o conteúdo de uma tabela

Este exemplo mostra a utilização de comandos SQL incorporados ao fonte do programa C. O programa estabelece uma conexão com o servidor de banco de dados por meio de soquete do domínio Unix, acessa o banco de dados teste através do usuário cujo nome é teste e cuja senha também é teste. Depois lista as linhas da tabela criada pelo script mostrado abaixo:

CREATE TABLE pessoal (id SERIAL PRIMARY KEY, nome VARCHAR(50));
INSERT INTO pessoal (nome) VALUES ('Maria');
INSERT INTO pessoal (nome) VALUES ('Manuel');
INSERT INTO pessoal (nome) VALUES ('Francisco');

Abaixo está mostrado o código fonte do programa pessoal.pgc.

/*
 * Programa para mostrar a utilização do SQL estático incorporado.
 * Baseado em:
 *     The art of metaprogramming, Part 1: Introduction to metaprogramming
 *     http://www-128.ibm.com/developerworks/linux/library/l-metaprog1.html
 */

#include <stdio.h>

/*
 * Rotina para tratamento de erro
 */

static void erro() {
   printf("#%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
   exit(1);
}

/*
 * Rotina para tratamento de advertência
 */

static void advertencia() {
   printf("#%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
}

int main()
{

   /*
    * Tratar os erros e advertências de forma apropriada
    */

   EXEC SQL WHENEVER SQLWARNING DO advertencia();   /* sqlca.sqlwarn[0] == 'W' */
   EXEC SQL WHENEVER SQLERROR DO erro();            /* sqlca.sqlcode < 0 */

   /*
    * Estabelecer a conexão com o servidor de banco de dados.
    * Usar o nome, senha e banco de dados apropriados.
    */

   EXEC SQL CONNECT TO unix:postgresql://localhost/teste USER teste/teste;

   /*
    * Variáveis utilizadas para armazenamento
    * temporário dos campos do banco de dados
    */

   EXEC SQL BEGIN DECLARE SECTION;
   int id;
   VARCHAR nome[200];
   EXEC SQL END DECLARE SECTION;

   /*
    * Declaração a ser executada
    */

   EXEC SQL DECLARE cursor_pessoal CURSOR FOR
      SELECT id, nome FROM pessoal ORDER BY nome;

   /*
    * Executar a declaração
    */

   EXEC SQL OPEN cursor_pessoal;

   EXEC SQL WHENEVER NOT FOUND GOTO fechar_cursor;
   while(1) /* a saída do laço é tratada pela declaração precedente */
   {
      /* Ler o próximo valor */
      EXEC SQL FETCH cursor_pessoal INTO :id, :nome;
      printf("Lido: ID = %d; Nome = %s\n", id, nome.arr);
   }

   /* Limpeza */
   fechar_cursor:
   EXEC SQL CLOSE cursor_pessoal;
   EXEC SQL DISCONNECT;

   return 0;
}

Abaixo está mostrado o script utilizado para a pré-compilação, compilação, criação do executável e execução do programa. Como a árvore de fontes não foi instalada (make install), foi apenas construída (make), é necessário informar os diretórios dos cabeçalhos, bibliotecas e programas.

#!/bin/sh
# Script para pré-compilar, compilar e executar o programa 'pessoal.pgc'
ecpg pessoal.pgc
gcc pessoal.c -o pessoal \
-I ~/postgresql-8.0.0/src/interfaces/ecpg/include/ \
-I ~/postgresql-8.0.0/src/interfaces/libpq/ \
-I ~/postgresql-8.0.0/src/include/ \
-L ~/postgresql-8.0.0/src/interfaces/ecpg/ecpglib/ \
-l ecpg
./pessoal

Por fim está mostrado o resultado da execução do programa.

Lido: ID = 3; Nome = Francisco
Lido: ID = 2; Nome = Manuel
Lido: ID = 1; Nome = Maria

Exemplo 29-2. Linguagem SQL estática incorporada

Este exemplo mostra a utilização de comandos SQL incorporados ao fonte do programa C. O programa estabelece uma conexão com o servidor de banco de dados por meio do TCP/IP, acessa o banco de dados teste através do usuário cujo nome é teste e cuja senha também é teste. Depois cria a tabela temporária filmes, carrega a tabela com os dados contidos na matriz filmes, e lista as linhas da tabela.

Abaixo está mostrado o código fonte do programa sta-select.pgc.

/*
 * Programa para mostrar a utilização do SQL estático incorporado.
 * Baseado em:
 *     Universidade de Toronto - DB2 -  Embedded SQL Examples
 *     http://www.cs.toronto.edu/db/courses/db2/
 */

#include <stdio.h>

/*
 * Declarar as variáveis do programa
 */

int i;

/*
 * Declarar as variáveis hospedeiras
 */

EXEC SQL BEGIN DECLARE SECTION;
    /* Propriedades do filme */
    int   filme_id;
    char  filme_titulo[20];
    char  filme_diretor[20];
    /* Propriedades da conexão com o servidor de banco de dados */
    char *conexao="tcp:postgresql://127.0.0.1:5432/teste";
    char *usuario="teste";
    char *senha="teste";
    /* Filmes */
    struct filme {
        int   filme_id;
        char  filme_titulo[20];
        char  filme_diretor[20];
    };
    struct filme filmes[] = {
        {100,"Água Negra","Walter Salles"},
        {200,"Aprendendo a Mentir","Hendrik Handloegten"},
        {300,"Guerra dos Mundos","Steven Spielberg"},
        {400,"Quarteto Fantástico","Tim Story"}
    };
EXEC SQL END DECLARE SECTION;

/*
 * As linhas abaixo são redundantes, porque a ação padrão é continuar.
 * Estas linhas apenas mostram as situações que podem ocorrer,
 * e uma forma de controlá-las.
 */

                                        /* sqlca.sqlcode == 0 (sem erro)   */
EXEC SQL WHENEVER SQLWARNING CONTINUE;  /* sqlca.sqlwarn[0] == 'W'         */
EXEC SQL WHENEVER NOT FOUND CONTINUE;   /* sqlca.sqlcode == ECPG_NOT_FOUND */

/*
 * Quando houver um erro executar a rotina de tratamento de erro.
 */

EXEC SQL WHENEVER SQLERROR DO erro();   /* sqlca.sqlcode < 0 */

/*
 * Rotina para tratamento de erro
 */

static void erro()
{  printf("#%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
   exit(1);
}

/*
 * Programa principal
 */

int main() {

/*
 * Conectar com o banco de dados
 */

EXEC SQL CONNECT TO :conexao USER :usuario IDENTIFIED BY :senha;

if (sqlca.sqlcode != 0) {
        printf("Falha na conexão!");
        erro();
}

/*
 * Criar a tabela filmes
 */

EXEC SQL CREATE TEMPORARY TABLE filmes (
    filme_id      INT NOT NULL PRIMARY KEY,
    filme_titulo  VARCHAR(20),
    filme_diretor VARCHAR(20)
);

/*
 * Inserir as linhas na tabela
 */

for (i=0; i<(sizeof(filmes)/sizeof(filmes[0])); i++) {
    EXEC SQL INSERT INTO filmes VALUES(
        :filmes[i].filme_id,:filmes[i].filme_titulo,:filmes[i].filme_diretor
    );
}

/*
 * Imprimir o cabeçalho da tabela
 */

 printf("+----------------------+----------------------+\n");
 printf("| Nome do filme        | Diretor              |\n");
 printf("+----------------------+----------------------+\n");

/*
 * Declarar um cursor para acessar as linhas da tabela
 */

EXEC SQL DECLARE c1 CURSOR FOR
    SELECT filme_titulo, filme_diretor
    FROM filmes;

/*
 * Abrir o cursor para ler as linhas da tabela
 */

EXEC SQL OPEN c1;

do {

  /*
   * Ler as linhas da tabela.
   * Executa a declaração implementada pelo cursor e retorna os resultados.
   */

  EXEC SQL FETCH c1 INTO :filme_titulo, :filme_diretor;
  if (SQLCODE != 0) break;  /* SQLCODE se refere a sqlca.sqlcode */

  /*
   * As variáveis hospedeiras devem ser prefixadas por ':'
   * quando são utilizadas nos comandos SQL
   */

  printf("| %-20s | %-20s |\n",filme_titulo,filme_diretor);

} while (1);

/*
 * Fechar a tabela
 */
 printf("+----------------------+----------------------+\n");

/*
 * Fechar o cursor e a conexão
 */

EXEC SQL CLOSE c1;
EXEC SQL DISCONNECT;
}

Abaixo está mostrado o script utilizado para a pré-compilação, compilação, criação do executável e execução do programa. Como a árvore de fontes não foi instalada (make install), foi apenas construída (make), é necessário informar os diretórios dos cabeçalhos, bibliotecas e programas.

#!/bin/sh
# Script para pré-compilar, compilar e executar o programa 'sta-select.pgc'
~/postgresql-8.0.0/src/interfaces/ecpg/preproc/ecpg sta-select.pgc
gcc sta-select.c -o sta-select \
-I ~/postgresql-8.0.0/src/interfaces/ecpg/include/ \
-I ~/postgresql-8.0.0/src/interfaces/libpq/ \
-I ~/postgresql-8.0.0/src/include/ \
-L ~/postgresql-8.0.0/src/interfaces/ecpg/ecpglib/ \
-lecpg
./sta-select

Por fim está mostrado o resultado da execução do programa.

+----------------------+----------------------+
| Nome do filme        | Diretor              |
+----------------------+----------------------+
| Água Negra           | Walter Salles        |
| Aprendendo a Mentir  | Hendrik Handloegten  |
| Guerra dos Mundos    | Steven Spielberg     |
| Quarteto Fantástico  | Tim Story            |
+----------------------+----------------------+

Exemplo 29-3. Linguagem SQL dinâmica incorporada

Este exemplo mostra a utilização de comandos SQL incorporados ao fonte do programa C. O programa estabelece uma conexão com o servidor de banco de dados por meio de soquete do domínio Unix, acessa o banco de dados teste através do usuário cujo nome é teste e cuja senha também é teste. Depois cria a tabela temporária filmes, carrega a tabela com os dados contidos na matriz filmes, e lista as linhas da tabela. Se o nome do filme ou o nome do diretor for uma cadeia de caracteres vazia, os indicadores sinalizam um valor nulo.

Abaixo está mostrado o código fonte do programa dyn-select.pgc.

/*
 * Programa para mostrar a utilização do SQL dinâmico incorporado.
 * Baseado em:
 *     Universidade de Toronto - DB2 -  Embedded SQL Examples
 *     http://www.cs.toronto.edu/db/courses/db2/
 */

#include <stdio.h>

/*
 * Declarar as variáveis do programa
 */

int i;

/*
 * Declarar as variáveis hospedeiras
 */

EXEC SQL BEGIN DECLARE SECTION;
    /* Propriedades do filme */
    int   filme_id;
    char  filme_titulo[20];
    char  filme_diretor[20];
    /* Propriedades da conexão com o servidor de banco de dados */
    char *conexao="unix:postgresql://localhost/teste";
    char *usuario="teste";
    char *senha="teste";
    /* Filmes */
    struct filme {
        int   filme_id;
        char  filme_titulo[20];
        char  filme_diretor[20];
    };
    struct filme filmes[] = {
        {100,"Água Negra","Walter Salles"},
        {200,"Aprendendo a Mentir","Hendrik Handloegten"},
        {300,"Guerra dos Mundos","Steven Spielberg"},
        {400,"Quarteto Fantástico","Tim Story"},
        {500,"Horror em Amityville",""}
    };
    /* Indicadores */
    int ind1, ind2, ind3;
    /* Declaração de inserção de filme */
    char *insere_filme = "INSERT INTO filmes VALUES(?, ?, ?);";
EXEC SQL END DECLARE SECTION;

/*
 * As linhas abaixo são redundantes, porque a ação padrão é continuar.
 * Estas linhas apenas mostram as situações que podem ocorrer,
 * e uma forma de controlá-las.
 */

                                        /* sqlca.sqlcode == 0 (sem erro)   */
EXEC SQL WHENEVER SQLWARNING CONTINUE;  /* sqlca.sqlwarn[0] == 'W'         */
EXEC SQL WHENEVER NOT FOUND CONTINUE;   /* sqlca.sqlcode == ECPG_NOT_FOUND */

/*
 * Quando houver um erro executar a rotina de tratamento de erro.
 */

EXEC SQL WHENEVER SQLERROR DO erro();   /* sqlca.sqlcode < 0 */

/*
 * Rotina para tratamento de erro
 */

static void erro()
{  printf("#%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
   exit(1);
}

/*
 * Programa principal
 */

int main() {

/*
 * Conectar com o banco de dados
 */

EXEC SQL CONNECT TO :conexao USER :usuario IDENTIFIED BY :senha;

if (sqlca.sqlcode != 0) {
        printf("Falha na conexão!");
        erro();
}

/*
 * Criar a tabela filmes
 */

EXEC SQL CREATE TEMPORARY TABLE filmes (
    filme_id      INT NOT NULL PRIMARY KEY,
    filme_titulo  VARCHAR(20),
    filme_diretor VARCHAR(20)
);

/*
 * Inserir as linhas na tabela
 */

EXEC SQL PREPARE insere_filme FROM :insere_filme;

for (i=0; i<(sizeof(filmes)/sizeof(filmes[0])); i++) {
    ind1 = ind2 = ind3 = 0;
    if (strlen(filmes[i].filme_titulo) == 0) ind2=-1;
    if (strlen(filmes[i].filme_diretor) == 0) ind3=-1;
    EXEC SQL EXECUTE insere_filme USING
        :filmes[i].filme_id:ind1,
        :filmes[i].filme_titulo:ind2,
        :filmes[i].filme_diretor:ind3;
}

/*
 * Imprimir o cabeçalho da tabela
 */

 printf("+----------------------+----------------------+\n");
 printf("| Nome do filme        | Diretor              |\n");
 printf("+----------------------+----------------------+\n");

/*
 * Declarar um cursor para acessar as linhas da tabela
 */

EXEC SQL DECLARE c1 CURSOR FOR
    SELECT filme_titulo, filme_diretor
    FROM filmes;

/*
 * Abrir o cursor para ler as linhas da tabela
 */

EXEC SQL OPEN c1;

do {

  /*
   * Ler as linhas da tabela.
   * Executa a declaração implementada pelo cursor e retorna os resultados.
   */

  EXEC SQL FETCH c1 INTO :filme_titulo:ind1, :filme_diretor:ind2;
  if (SQLCODE != 0) break;  /* SQLCODE se refere a sqlca.sqlcode */
  /* Verificar valores nulos */
  if (ind1 == -1) {
     strcpy(filme_titulo,"-");
  }
  if (ind2 == -1) {
     strcpy(filme_diretor,"-");
  }

  /*
   * As variáveis hospedeiras devem ser prefixadas por ':'
   * quando são utilizadas nos comandos SQL
   */

  printf("| %-20s | %-20s |\n",filme_titulo,filme_diretor);

} while (1);

/*
 * Fechar a tabela
 */
 printf("+----------------------+----------------------+\n");

/*
 * Fechar o cursor e a conexão
 */

EXEC SQL CLOSE c1;
EXEC SQL DISCONNECT;
}

Abaixo está mostrado o script utilizado para a pré-compilação, compilação, criação do executável e execução do programa. Como a árvore de fontes não foi instalada (make install), foi apenas construída (make), é necessário informar os diretórios dos cabeçalhos, bibliotecas e programas.

#!/bin/sh
# Script para pré-compilar, compilar e executar o programa 'dyn-select.pgc'
~/postgresql-8.0.0/src/interfaces/ecpg/preproc/ecpg dyn-select.pgc
gcc dyn-select.c -o dyn-select \
-I ~/postgresql-8.0.0/src/interfaces/ecpg/include/ \
-I ~/postgresql-8.0.0/src/interfaces/libpq/ \
-I ~/postgresql-8.0.0/src/include/ \
-L ~/postgresql-8.0.0/src/interfaces/ecpg/ecpglib/ \
-lecpg
./dyn-select

Abaixo estão mostradas as linhas inseridas no começo do arquivo fonte C pelo pré-compilador.

/* Processed by ecpg (3.2.0) */
/* These include files are added by the preprocessor */
#include <ecpgtype.h>
#include <ecpglib.h>
#include <ecpgerrno.h>
#include <sqlca.h>
/* End of automatic include section */
#line 1 "dyn-select.pgc"

Por fim está mostrado o resultado da execução do programa.

+----------------------+----------------------+
| Nome do filme        | Diretor              |
+----------------------+----------------------+
| Água Negra           | Walter Salles        |
| Aprendendo a Mentir  | Hendrik Handloegten  |
| Guerra dos Mundos    | Steven Spielberg     |
| Quarteto Fantástico  | Tim Story            |
| Horror em Amityville | -                    |
+----------------------+----------------------+
SourceForge.net Logo CSS válido!