quarta-feira, 18 de agosto de 2010

Evento Discovery Informix Brasil - Agosto/2010

Semana que vem ocorrerá o Discovery Informix Brasil, evento que apresentará os recursos e as novidades deste banco de dados, e que contará com as presenças de:


Jerry Keesee - Director of Informix Database Development - ("o cara que faz o informix")
Stuart Litel - International Informix Users Group – President
Miguel Carbone - International Informix Users Group – Board of Directors

Agenda:

Dia 26/08/2010 - São Paulo
Dia 27/08/2010 - Rio de Janeiro
Dia 31/08/2010 - Belo Horizonte

Maiores detalhes em:

http://www.imartins.com.br/informix/artigos/evento-discovery-informix-sao-paulo-rio-janeio-belo-horizonte
http://informixbr.blogspot.com/2010/08/evento-informix-em-2608-nao-perca.html

sábado, 7 de agosto de 2010

Concatenar strings em registros diferentes - WM_Concat

Na sua empresa há uma tabela de Funcionários e outra de dependentes, conjuge, filhos, etc...) de cada funcionário. Há, portanto, duas tabelas: Funcionario( Func_ID, Nome, Dt_Nasc) e Dependente(Dep_ID, Func_ID, Nome, Relacao). É um tradicional relacionamento 1-N.

Como exemplo:

TABELA FUNCIONARIO
IDNOMEDT_NASC
1João25/12/1980
2Maria04/04/1987
3Paulo29/09/1984

TABELA DEPENDENTE
DEP_IDFUNC_IDNOMERELACAO
11Ana MariaConjuge
21Ana PaulaFilho(a)
31João JrFilho(a)
42CarlosConjuge
53PedroFilho(a)
63JuliaFilho(a)

Então, preparando uma festa de dia das crianças para os filhos do funcionário, alguém solicita um relatório com o nome do funcionário e o nome de todos seus filhos. Detalhe: todos em uma mesma coluna. Portanto, para atender à solicitação, teríamos:

RELATÓRIO DOS FILHOS
NOME DO FUNCIONÁRIOLISTA DE FILHOS(AS)
JoãoAna Paula, João Jr
Maria
PauloPedro, Julia

As tabelas de Funcionários e Dependentes podem ser criadas como views temporárias, apenas para uso nas queries de teste, pelo comando:

with funcionario as

(select 1 FUNC_ID, 'João' Nome, to_date('25/12/1980', 'dd/mm/yyyy') Dt_Nasc from dual union all
select 2 FUNC_ID, 'Maria' Nome, to_date('04/04/1987', 'dd/mm/yyyy') Dt_Nasc from dual union all
select 3 FUNC_ID, 'Paulo' Nome, to_date('29/09/1984', 'dd/mm/yyyy') Dt_Nasc from dual),
dependente as
(select 1 DEP_ID, 1 FUNC_ID, 'Ana Maria' Nome, 'Conjuge' Relacao from dual union all
select 2 DEP_ID, 1 FUNC_ID, 'Ana Paula' Nome, 'Filho(a)' Relacao from dual union all
select 3 DEP_ID, 1 FUNC_ID, 'João Jr' Nome, 'Filho(a)' Relacao from dual union all
select 4 DEP_ID, 2 FUNC_ID, 'Carlos' Nome, 'Conjuge' Relacao from dual union all
select 5 DEP_ID, 3 FUNC_ID, 'Pedro' Nome, 'Filho(a)' Relacao from dual union all
select 6 DEP_ID, 3 FUNC_ID, 'Julia' Nome, 'Filho(a)' Relacao from dual )


No Oracle há uma função não documentada, WM_CONCAT, que pode ser utilizada como uma função agregadora, da mesma forma que as habituais MAX, MIN, SUM e AVG. A query seria:

select f.nome, WM_CONCAT(d.nome)
  from funcionario f,
       dependente d
 where f.func_id = d.func_id
   and d.relacao = 'Filho(a)'
 group by f.nome;

Os valores são separados por vírgula. Caso seja necessário, a função REPLACE pode substituir a vírgula. eu usei para acrescentar um espaço após a vírgula, deste modo:

select f.nome, replace(WM_CONCAT(d.nome), ',', ', ')
  from funcionario f,
       dependente d
 where f.func_id = d.func_id
   and d.relacao = 'Filho(a)'
 group by f.nome;

Por último, uma palavra de precaução: como esta função não é documentada, a Oracle tem liberdade para numa próxima versão alterar o funcionamento ou simplesmente removê-la. Sendo assim, utilizá-la numa query para atender um demanda momentânea é seguro. Já utilizá-la em uma solução definitiva ou que deva rodar em várias versões de Oracle, é menos recomendável.