terça-feira, 9 de outubro de 2007

Variaveis de sessão usando Pl Python

Olá pessoal, vamos apresentar aqui como implementar no postgreSQL um recurso de variáveis de sessão, que pode ser inclusive usado para "substituir" o uso das variáveis de pacotes do oracle.

Primeiro fizemos a intalação do plpython no fedora 7

wget http://ftp.gui.uva.es/sites/fedora.redhat.com/linux/updates/7/i386/postgresql-plpython-8.2.4-1.fc7.i386.rpm
rpm -ivh postgresql-plpython-8.2.4-1.fc7.i386.rpm



Em seguida instalamos a plpython no banco de dados de trabalho:

createlang plpythonu detran


A pl python tem um recurso interessante que é um dicionário de dados de acesso global dentro de uma sessão, com isso podemos criar 2 funções em python set_session e get_session que vão fazer o trabalho de setar e ler essas variáveis em qualquer local que venhamos a precisar.

Para setar as informações de sessão em python usamos:

GD["nome_var"] = "valor"

para ler o valor da variável usamos apenas

GD["nome_var"]


Abaixo as funcões para gravar e ler as variáveis.

CREATE OR REPLACE FUNCTION set_session(var1 "varchar", var2 "varchar")
RETURNS bool AS
$$
GD[args[0]] = args[1]
return True
$$
LANGUAGE 'plpythonu' VOLATILE;

CREATE OR REPLACE FUNCTION get_session(var1 "varchar")
RETURNS varchar AS
$$
return GD[args[0]]
$$
LANGUAGE 'plpythonu' VOLATILE;


Para testar:
select set_global('nome','coutinho'); # retorna true se nao der pau
select get_global('nome'); # retorna 'coutinho'

sexta-feira, 5 de outubro de 2007

NVL parte 2

Descobrimos depois o tipo anyelement, agora a função NVL pode ser escrita também da forma abaixo, dispensando a sobrecarga

CREATE OR REPLACE FUNCTION nvl (anyelement, anyelement) RETURNS anyelement AS
$body$
select coalesce($1,$2);
$body$ language 'sql';

quinta-feira, 4 de outubro de 2007

Exportação da estrutura do banco de dados - parte 1

Olá pessoal, nesse meu primeiro post aqui Postmaster Ceará eu vou falar sobre o ora2pg, que é uma ferramenta escrita em perl que facilita um bocado a vida de quem tem que migrar uma base de dados do Oracle para o PostgreSQL.

O ora2pg se conecta ao banco de dados pode exportar a estrutura e os dados para um script sql ou direto para dentro de uma base de dados PostgreSQL.

É fácil testar o ora2pg e ver sua eficiência, para isso vamos precisar de:

  • banco de dados oracle com alguns objetos
  • banco de dados postgresql vazio

Na máquina onde iremos rodar o ora2pg precisaremos de:
  • perl
  • oracle cliente
  • modulo DBD do perl para conexão com oracle

Então vamos parar de papo e vamos baixar o ora2pg, instalar, configurar e exportar nosso banco de dados de teste do oracle para o postgreSQL . Supondo que você use um sistema operacional descente, a gente poderia fazer assim

Baixar o ora2pg
wget http://freshmeat.net/redir/ora2pg/20708/url_tgz/ora2pg-4.5.tar.gz

Baixar o driver perl de aceso ao oracle (DBD::Oracle)
wget http://search.cpan.org/CPAN/authors/id/P/PY/PYTHIAN/DBD-Oracle-1.19.tar.gz

Baixar o driver perl de aceso ao PostgreSQL (DBD::Pg)
wget http://search.cpan.org/CPAN/authors/id/D/DB/DBDPG/DBD-Pg-1.49.tar.gz


Instalar o DBD::Oracle
tar zxvf DBD-Oracle-1.19.tar.gz
cd DBD-Oracle-1.19
perl Makefile.PL
make
make install

Instalar o DBD::Pg
tar zxvf DBD-Pg-1.49.tar.gz
cd DBD-Pg-1.49
perl Makefile.PL
make
make install

O ora2pg na realidade não necessita de nenhum proceso de instalação e a única coisa que precisamos fazer para usa-lo é descompactalo em algum lugar:

tar zxvf ora2pg-4.5.tar.gz


Com isso agora nós poderíamos inicar o porceso de configuração e testar a exportação de nossa base de dados, mas para dar um pouco mais de audiência ao blog isso vai ficar para a "parte 2" desse pequeno tutorial.

quarta-feira, 3 de outubro de 2007

Operação de Divisão

Algumas dicas para operação de divisão:

select 5 / 2; ==> 2

select 5::float /2; ==> 2.5

select 5::float / 2::float; ==> 2.5

select 5.0 / 2.0; ==> 2.5

terça-feira, 2 de outubro de 2007

Conexão do PostgreSQL com o Java

No DETRAN-CE, os sistemas finalísticos foram desenvolvidos em Java, para testar a conexão do PostgreSQL com o Java podem ser utilizados inúmeros clientes de gerenciamento ou modelagem do PostgreSQL. No exemplo que vou mostrar abaixo, utilizei o driver JDBC. O driver JDBC a ser utilizado deve estar de acordo com a versão do PostgreSQL, entretanto temos instalado a versão 8.2.4 do banco e nos testes ela só funcionou com o driver 8.1-410.jdbc3, quando o correto seria utilizar a versão 8.2-506.jdbc4. Ainda estou realizando mais alguns uns testes para entender o que ocorreu.No exemplo abaixo criei uma tabela com dados de livros (id, nome, autor, editor, ano) e me conectei ao postgres para retornar uma consulta simples.

// início da aplicação

import java.sql.*;
public class SQLStatement {
public static void main(String args[]) {
String url = "jdbc:postgresql://host:5432/nomedobanco";
Connection con;
String query = "select * from nomedoesquema.nomedatabela";
Statement stmt;
try {
Class.forName("org.postgresql.Driver");
} catch(java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}
try {
con = DriverManager.getConnection(url,"login", "senha");
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
int rowCount = 1;
System.out.println("Cadastro de Livros");
while (rs.next()) {
System.out.println("Livro " + rowCount);
for (int i = 1; i <= numberOfColumns; i++) {
System.out.print(" Campo " + i + ": ");
System.out.println(rs.getString(i));
}
System.out.println("");
rowCount++;
}
stmt.close();
con.close();
} catch(SQLException ex) {
System.err.print("SQLException: ");
System.err.println(ex.getMessage());
}
}
}

// fim da aplicação

  • RESULTADO DA EXECUÇÃO UTILIZANDO O JDBC 8.1-410.jdbc3

Cadastro de Livros
Livro 1
Campo 1: 3
Campo 2: Estratégia empresarial : tendências e desafios
Campo 3: TACHIZAWA
Campo 4: Makron Books
Campo 5: 2000

Livro 2
Campo 1: 2
Campo 2: Como inovar na empresa através da tecnologia da informação
Campo 3: DAVEPORT
Campo 4: Campus
Campo 5: 1994

Livro 3:
Campo 1: 1
Campo 2: O Planej Estratégico dentro do Conceito de Adm Estratégica
Campo 3: ALDAY
Campo 4: FAE
Campo 5: 2006


  • RESULTADO DA EXECUÇÃO UTILIZANDO O JDBC 8.2-506.jdbc4

Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version number in .class file
at java.lang.ClassLoader.defineClass1(
Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(
Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at java.lang.Class.forName0(
Native Method)
at java.lang.Class.forName(Unknown Source)
at SQLStatement.main(
SQLStatement.java:11)

segunda-feira, 1 de outubro de 2007

To_Date X To_Timestamp

Tanto no ORACLE quanto no POSTGRES temos a função TO_DATE, só que no postgres ela se comporta de forma diferente. No ORACLE ,To_date converte uma string em data, semelhante ao postgres, a diferença é que no postgres ela só retorna a parte data enquanto que no ORACLE ela traz data e hora.

No Oracle

SQL> alter session set NLS_DATE_FORMAT='dd/mm/yyyy hh24:mi:ss';

Sessão alterada.

SQL> SELECT TO_DATE('01/10/2007') DATA FROM DUAL;

DATA
-------------------
01/10/2007 00:00:00

SQL> SELECT TO_DATE('01/10/2007 13:00:00','DD/MM/YYYY HH24:MI:SS') DATA FROM DUAL;

DATA
-------------------
01/10/2007 13:00:00



No postgres

select TO_date('01/10/2007','DD/MM/YYYY');
select TO_date('01/10/2007 13:00:00','DD/MM/YYYY HH24:MI:SS');

retorna das duas é o mesmo ==> 01/10/2007, não existe a hora

Para exibição da hora existe 2 alternativas

1.) Trocar a função to_date para to_timestamp, opções de máscaras semelhante da to_date
select TO_timestamp('01/10/2007 13:00:00','DD/MM/YYYY HH24:MI:SS');

2.) Criar uma função to_date que internamente chama a to_timestamp.

Aqui no detran adotaremos a primeira opção.

Função NVL

Um dos pontos importantes para o sucesso do projeto é referente a menor quantidade de alteração do código já existente. Tentar compatibilizar as funções usadas no ORACLE, consiste em uma das tarefas de preparação do ambiente a fim de manter padrão o leque de funções já usadas. Nas próximas postagens estaremos falando destas compatibilizações, O NVL será a primeira função apresentada.

  1. NLV(P1, P2) -> Retorna o P2 caso P1 seja nulo
Como P1 pode ser de qualquer tipo , criamos para o postgres através de sobrecarga de função, várias funções NVL alterando o tipo de P1
    • NVL(Varchar, Varchar)
    • NLV(Date,Date)
    • NVL(Integer,Integer)
    • NVL(Timestamp,Timestamp)
    • NVL(Numeric,Numeric)
Internamente na função faz chamada a função COALESCE do postgres que faz o que o NVL faz no Oracle.

Código pl/pgSQL para o tipo varchar

CREATE OR REPLACE FUNCTION nvl (valor varchar, valor_padrao varchar) RETURNS varchar AS
$body$
declare retorno varchar;
begin
select into retorno coalesce(valor,valor_padrao);
return retorno;
end;
$body$
LANGUAGE 'plpgsql'

by TemplatesForYouTFY
SoSuechtig, Burajiru