terça-feira, 23 de dezembro de 2008

Boas Festas!!!


Não sou o primeiro, nem quero ser o último a desejar a você boas festas e um abençoado 2009!!!

DbDesigner Fork: Fraco, mas Gratuito!

Ferramentas para projeto de banco de dados estão entre as mais úteis para o desenvolvimento de sistemas. Infelizmente, também estão entre as mais difíceis de se encontrar dentre os softwares gratuitos. O DbDesigner Fork é uma boa opção livre para a modelagem de bancos de dados, apresentando suporte para Oracle, SQL Server, MySql e Firebird, além do PostgreSQL.

O projeto está disponível para Windows e Linux e sua última versão está datada de julho de 2007. Originou-se do DBDesigner, uma ferramenta mais antiga. Seu desenvolvimento apresenta alguma taxa de atividade e possivelmente será feito algum novo release em breve. Gera arquivos XML com a modelagem realizada em uma boa interface visual.

Apresenta uma série de recursos bastante úteis:
- Engenharia Reversa
- Sincronização
- Modelagem visual de diagramas de Entidade-Relacionamento, com integridade referencial
- Recursos para exportação SQL
- Importação da ferramenta ErWin
- Exportação dos diagramas como figuras (PNG e BMP)

DbDesigner e PostgreSQL

Nesta análise me concentrarei basicamente nas características específicas que o software tem em relação com o o PostgreSQL. A ferramenta apresentou um resultado razoável, pois foram constatados bugs e limitações. O ponto forte, além da gratuidade, foi a interface amigável, apesar de não tão moderna.

A conexão com o banco foi dificultada pelo fato da ferramenta só aceitar conexão ODBC com o PostgreSQL. Tive de baixar e instalar o driver ODBC, além de criar um data source no sistema operacional.


A interface visual é simples e a seleção da visualização em query mode permitiu a realização de consultas ao SGBD sem sair da ferramenta.


A engenharia reversa funcionou muito bem. Puxou os dados do PostgreSQL rapidamente e criou objetos no diagrama corrente. No entanto, não importou as chaves estrangeiras. Quando realizada mais de uma vez, criou mais de uma tabela com o mesmo nome no diagrama.


A sincronização de banco de dados simplesmente não funcionou. Fiquei em dúvida se a mensagem de erro apresentada foi em virtude de bug da ferramenta ou da versão do driver ODBC utilizada. Abaixo, a tela de sincronização:



Na exportação de dados, uma decepção: não há ligação direta para o PostgreSQL. O DbDesigner exporta um script SQL que deve ser submetido ao banco.

Avaliação geral

Creio que houve uma série de avanços em relação às versões anteriores da ferramenta, mas ainda está distante de ser utilizável sem ressalvas, especialmente nas grandes empresas. Abaixo listo algumas das limitações da ferramenta:

- Falta Suporte a trabalho em grupos.
- Ausência de Controle de versões.
- Grande espaçamento de tempo entre as atualizações de versão.
- Número grande de bugs e de requested features por atender.
- Falta de interface WEB

Observações

Aconselho a quem deseja utilizar esta ferramenta para suas aplicações que preserve o modelo gerado, que é criado em formato XML, em uma ferramenta de controle de versões. Em releases anteriores do DbDesigner cheguei a perder algumas horas de trabalho por corrupção do arquivo.

sexta-feira, 5 de dezembro de 2008

Retornando registros de consultas genéricas com RETURN QUERY

Recentemente, recebi uma dúvida sobre o RETURN QUERY, funcionalidade implementada na versão 8.3 do PostgreSQL, que permite o retorno de conjuntos de linhas e colunas de uma função. A dúvida do Patrick é bastante comum e até pouco tempo eu não teria uma resposta adequada:


"Patrick Espake disse...

Eu estou tentando usar isso, para retorna uma linha que vem de um inner join de diversas tabelas.

O que eu coloco para o RETURNS SETOF? Visto que os meus dados vem de uma junção de diversas tabelas.

Obrigado."


A solução do problema do Patrick é relativamente simples. O Return Query aceita o tipo RECORD como valor de retorno. Portanto, fica fácil retornar resultados de consultas genéricas. Para ilustrar, segue um exemplo de código Pl/ PgSQL abaixo.

A tabela indivíduo será utilizada para o teste do RETURN QUERY retornando uma consulta qualquer.

CREATE TABLE individuo (
cod integer PRIMARY KEY,
nome varchar(50));
INSERT INTO individuo VALUES (1,'Teste');
INSERT INTO individuo VALUES (2,'Teste 2');

Agora, a função RET_ROWS mostra como utilizar o retorno de tipos RECORD para funções:

--Retornando consulta de várias linhas
CREATE OR REPLACE FUNCTION ret_rows () RETURNS SETOF RECORD AS $$
BEGIN
RETURN QUERY SELECT * FROM individuo; -- Acrescenta um conjunto de linhas ao retorno da função
RETURN ; -- Retorna as linhas
END;
$$ LANGUAGE plpgsql;

A grande diferença desta forma de programar está na chamada da função. Ao utilizar valor de retorno do tipo RECORD, deve ser indicada a lista de campos a serem retornados e seus tipos. Esta pode ser vista como uma limitação, embora na prática também seja uma forma de se garantir a confiabilidade dos resultados retornados na execução de comandos SQL dentro de funções pela validação dos valores retornados.

SELECT * from ret_rows() as (c1 integer, c2 varchar(50)) ; --Declaração dos campos do record

Falta considerar a execução de uma junção dentro da função, que é nossa questão original. Para tanto, será criada uma tabela com os filhos dos indivíduos para sofrer junção com a de indivíduos. O exemplo abaixo executou sem qualquer problema na versão 8.3:

CREATE TABLE filhos (
cod integer PRIMARY KEY,
filhos integer);
INSERT INTO filhos VALUES (1,1);
INSERT INTO filhos VALUES (2,3);

--Retornando Resultado de Junção
CREATE OR REPLACE FUNCTION ret_filhos (psql integer) RETURNS SETOF RECORD AS $$
BEGIN
RETURN QUERY SELECT individuo.nome, filhos.filhos FROM individuo, filhos WHERE individuo.cod = filhos.cod AND individuo.cod = $1; -- Consulta
RETURN ; -- Retorna as linhas
END;
$$ LANGUAGE plpgsql;

SELECT * from ret_filhos(1) as (c1 varchar(50), c2 integer) ; --Declaração dos campos de retorno
SELECT * from ret_filhos(2) as (c1 varchar(50), c2 integer) ;

Outras Soluções


Outras soluções para o retorno de registros em funções são a consolidação e retorno dos dados dentro de um campo texto ou XML.

Resolveu, Patrick?