.comment-link {margin-left:.6em;}

Friday, March 31, 2006

COLLECT

Mais um ponto positivo para performance no 10g. A função de agregação COLLECT agrupa valores de uma coluna. A vantagem aqui é o ganho de performance já que a função é built-in, nativa, portanto evita o switch de contexto entre as engines.

No exemplo: eu criei uma type de tabela varchar2 para receber o valor do agrupamento.
Caso não exista a type o Oracle cria durante a execução com um nome estranho, como visto em negrito abaixo.

SQL> select deptno, collect( ename ) ename from emp group by deptno;

DEPTNO ENAME
------------- ----------------------------------------------------------------------
10 SYSTPEEPvmSZz7KjgQAB/AQAZCw==('CLARK', 'KING', 'MILLER')
...

Na sequência, uma pequena função para limpar a type e deixar o resultado "limpo" e finalmente a execução da query com o uso da função COLLECT.

SQL> create or replace type vc2 as table of varchar2(4000);
2 /

Type created.

SQL> create or replace
2 function clean_vc2 (
3 p_vc2 in vc2,
4 p_dl in varchar2 default ','
5 ) return varchar2
6 is
7 i number;
8 l_string long;
9 l_delim varchar2(20);
10 begin
11 i := p_vc2.first;
12 while i is not null
13 loop
14 l_string := l_string || l_delim || p_vc2(i);
15 l_delim := p_dl;
16 i := p_vc2.next(i);
17 end loop;
18 return l_string;
19 end;
20 /

Function created.

SQL> show error
No errors.
SQL>
SQL> column ename format a70
SQL>
SQL> select deptno, clean_vc2( cast( collect(ename) as vc2 ) ) ename
2 from emp
3 group by deptno
4 /

DEPTNO ENAME
------------- ---------------------------------------------------------
10 CLARK,KING,MILLER
20 SMITH,JONES,SCOTT,ADAMS,FORD
30 ALLEN,WARD,MARTIN,BLAKE,TURNER,JAMES

3 rows selected.

Labels:


Tuesday, March 28, 2006

Plantão DBA

Recentemente, onde trabalho, foi instituído um rodízio para os DBAs ficarem de plantão a noite. Portanto, numeramos todos os seis e distribuímos por semana.

Na distribuição, quem cai na sexta ou véspera de feriado, fica com o fim de semana ou o feriado (pior quando é feriadão!). Logo me vi fazendo a escala no Excel. Ai eu parei e pensei: não tem algo errado? Sim, tinha. Eu tinha que usar o Oracle para calcular a escala ;)

Ai criei uma tabela de feriado para ajudar na composição da escala e o início do rodízio foi segunda, 20 de março. Ficou mais ou menos assim:

Ahhh... eu sou o DBA #2.

SQL> create table feriado ( dt_f date primary key ) organization index ;

Table created.

SQL> insert into feriado values (to_date('14/04/2006','dd/mm/yyyy'));

1 row created.

SQL> insert into feriado values (to_date('21/04/2006','dd/mm/yyyy'));

1 row created.

SQL> insert into feriado values (to_date('01/05/2006','dd/mm/yyyy'));

1 row created.

SQL> commit;

Commit complete.

SQL>
SQL> with
2 plantao as (
3 select to_date('20/03/2006', 'dd/mm/yyyy') + (level-1) dt
4 from dual
5 connect by level <= to_date('06', 'mm') - trunc(sysdate)
6 )
7 select nvl(a.dt, b.dt) dt, a.sem, a.dba
8 from (
9 select dt, to_char(dt, 'Day') sem,
10 decode(mod(rownum,6),0,6,mod(rownum,6) ) dba
11 from plantao
12 where to_char(dt, 'd') not in (1, 7)
13 and dt not in ( select dt_f from feriado )
14 ) a right outer join plantao b on (a.dt = b.dt)
15 order by 1
16 /

DT SEM DBA
--------- --------- -------------
20/MAR/06 Monday 1
21/MAR/06 Tuesday 2
22/MAR/06 Wednesday 3
23/MAR/06 Thursday 4
24/MAR/06 Friday 5
25/MAR/06
26/MAR/06
27/MAR/06 Monday 6
28/MAR/06 Tuesday 1
29/MAR/06 Wednesday 2
30/MAR/06 Thursday 3
31/MAR/06 Friday 4
01/APR/06
02/APR/06
03/APR/06 Monday 5
04/APR/06 Tuesday 6
05/APR/06 Wednesday 1
06/APR/06 Thursday 2
07/APR/06 Friday 3
08/APR/06
09/APR/06
10/APR/06 Monday 4
11/APR/06 Tuesday 5
12/APR/06 Wednesday 6
13/APR/06 Thursday 1
14/APR/06
15/APR/06
16/APR/06
17/APR/06 Monday 2
18/APR/06 Tuesday 3
19/APR/06 Wednesday 4
20/APR/06 Thursday 5
21/APR/06
22/APR/06
23/APR/06
24/APR/06 Monday 6
25/APR/06 Tuesday 1
26/APR/06 Wednesday 2
27/APR/06 Thursday 3
28/APR/06 Friday 4
29/APR/06
30/APR/06
01/MAY/06
02/MAY/06 Tuesday 5
03/MAY/06 Wednesday 6
04/MAY/06 Thursday 1
05/MAY/06 Friday 2
06/MAY/06
07/MAY/06
08/MAY/06 Monday 3
09/MAY/06 Tuesday 4
10/MAY/06 Wednesday 5
11/MAY/06 Thursday 6
12/MAY/06 Friday 1
13/MAY/06
14/MAY/06
15/MAY/06 Monday 2
16/MAY/06 Tuesday 3
17/MAY/06 Wednesday 4
18/MAY/06 Thursday 5
19/MAY/06 Friday 6
20/MAY/06
21/MAY/06
22/MAY/06 Monday 1
23/MAY/06 Tuesday 2

65 rows selected.

Labels:


Monday, March 27, 2006

Silêncio

O silêncio no blog foi difícil. Não ter tempo para algumas palavrinhas. Argh!

E tem tanta coisa nova. Quando tiramos um tempo para estudo, nota-se o quanto podemos melhorar.

Ok, esta entrada tem apenas a intenção de pedir desculpa pelo longo tempo sem postar nada. Espero colocar vários posts ao longo da semana.

Abraços,

This page is powered by Blogger. Isn't yours?