*/

quarta-feira, 16 de fevereiro de 2011

O Desafio do UNION

Esse desafio foi lançado por Arlindo, amigo e companheiro de trabalho, essa poderia ser uma questão de concurso público... e que muitos se atrapalhariam na hora de responder.

Vamos a Pergunta!

Levando em consideração que as duas querys abaixo, retornam o mesmo valor, a primeira roda no Postgres, MySQL e SQL Server e a segunda no Oracle.
Qual o valor de retorno delas? (Não vale colar! Responda sem executar a query!)

--No Postgres, MySQL, SQL Server 
     SELECT sum(x.a) 
       FROM 
          (
               SELECT 10 AS a
               UNION
               SELECT 10 AS a
          ) x
          ;

--No Oracle  
     SELECT sum(x.a) 
       FROM 
          (
               SELECT 10 AS a FROM dual
               UNION 
               SELECT 10 AS a FROM dual
          ) x
          ;          


Opções:

a)20
b)40
c)10
d)0
e)NULL

segunda-feira, 14 de fevereiro de 2011

Formatando nomes, colocando iniciais em maiúsculas e demais em minúsculas

É raro, mas, as vezes acontece de que o DBA Postgres, ter que adaptar um estrutura de nomes em uma ou mais tabelas, com iniciais em maiúsculas e demais e minúsculas, aqui segue um store function para fazer esse moido.

--
-- Nome Artefato/Programa..: sf_formata_nome.sql
-- Autor(es)...............: Emerson Hermann (emersonhermann@gmail.com) 
-- Data Inicio ............: 07/02/2011
-- Data Atual..............: 14/02/2011
-- Versao..................: 0.01
-- Compilador/Interpretador: PostgreSql
-- Sistemas Operacionais...: Linux/Windows
-- SGBD....................: PostgreSql 9.x
-- Kernel..................: Nao informado!
-- Finalidade..............: store function para formata um nome, colocando iniciais em maiúsculas e demais em minúsculas
-- OBS.....................: uso de função de agregacao array_agg funciona no PG 8.4 / 9.0, substituir por array_accum no PG anterior a essas versões .
--

-- Apaga function se existir 
DROP FUNCTION IF EXISTS sf_formata_nome(text);
CREATE OR REPLACE FUNCTION sf_formata_nome(var text) RETURNS TEXT AS
$body$
SELECT array_to_string(array_agg(nomes),' ')
  FROM  
     (
  SELECT CASE WHEN lower(x.id_unico[i]) = 'de' THEN
                 lower(x.id_unico[i])
              WHEN lower(x.id_unico[i]) = 'dos' THEN
                 lower(x.id_unico[i])
              WHEN lower(x.id_unico[i]) = 'da' THEN 
                 lower(x.id_unico[i])
              WHEN lower(x.id_unico[i]) = 'e' THEN 
                 lower(x.id_unico[i])                 
              ELSE  
                 upper(substring(x.id_unico[i],1,1)) || lower(substring(x.id_unico[i],2)) 
         END AS nomes
    FROM 
       (
        SELECT * 
   FROM string_to_array(cast($1 AS text),' ') AS id_unico
       ) AS x,  
       generate_series(1,array_upper(string_to_array(cast($1 as text),' '),1)) AS i

     ) AS x 
     ; 
$body$ 
LANGUAGE 'sql';
COMMENT ON FUNCTION sf_formata_nome(text) IS 'Função que formata um nome, colocando iniciais em maiúsculas e demais em minúsculas';

SELECT sf_formata_nome('JOSE E SILVA DE LIRA DOS SANTOS');

Pós Replicação no Postgres 9.0

Em outubro de 2010, publiquei um artigo no blog sobre como fazer replicação no Postgres 9.0 com Slackware 13.0, este mini artigo que escrevo agora, segue uma sugestão de solução na pós replicação.

Um problema que foi detectado, era o que fazer com tantos arquivos gerados no ponto de montagem na partição nfs, remover a cada sete dias seria uma possível solução, mas não seria confiável, a dica sugerida aqui está no diretório contrib do próprio Postgres e que se chama pg_arquivecleanup, tomando por base os fontes do Postgres vamos instalar essa contrib

#cd /usr/local/postgres-9.0.2/contrib/pg_arquivecleanup 

#make pg_arquivecleanup 

#make install pg_arquivecleanup 


Feito isso será criado uma arquivo binário chamado chamado pg_arquivecleanup no diretório de binários, default do Postgres em /usr/local/pgsql/bin

Depois adicionar no final do arquivo recovery.conf, este usado apenas nos slaves, a chamada do pg_archivecleanup, para isso, adicionando a seguinte linha: archive_cleanup_command = 'pg_archivecleanup /path/for/backups %r', conforme exemplo abaixo:

#echo archive_cleanup_command = 'pg_archivecleanup /mnt/postgres %r' >>  /usr/local/pgsql/data/recovery.conf 

#cat /usr/local/pgsql/data/recovery.conf  

standby_mode = 'on'

primary_conninfo = 'host=10.3.128.1 port=5432 user=postgres password=postgres'

restore_command = 'cp /mnt/postgres/%f %p'

trigger_file = '/tmp/trigger.pgsql.5432'

archive_cleanup_command = 'pg_archivecleanup  /mnt/postgres %r'

Após isso dá um restart no serviço do Postgres no(s) servidor(es) slave(s).

A contrib pg_archivecleanup remove os fragmentos da replicação de forma confiável, evitando que ocupe espaço desnecessário no servidor do banco.


Espero ter ajudado

O Peregrino.