Documentação do PostgreSQL 8.0.0 | ||||
---|---|---|---|---|
Anterior | Início | Capítulo 29. ECPG - SQL incorporado à linguagem C | Fim | Próxima |
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 | - | +----------------------+----------------------+