| 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 | - | +----------------------+----------------------+