GUOB Tech Day 2016 – Inscrições abertas

Olá PessoALL,

Estão abertas as inscrições para o GUOB Tech Day 2016.

 

Mais um ano do evento que junta todos nós profissionais que trabalham com ORACLE.

Este ano promete, teremos muitos nomes famosos palestrando e que com certeza vão contribuir muito para nossa evolução profissional.

Estarão presentes palestrantes como Osama Mustafa, Tim Gorman, Daniel Morgan , Kyle Hailey, Kuassi Mensah, Glenn Schwartzberg, entre outros.

Então, já faça sua inscrição e garanta participação no evento!

Mais detalhes clique aqui.

Grande abraço!!!

Manipulando campo XML – Oracle 11gR2

Olá PessoALL!!

Recebi um comentário aqui no site de um leitor perguntando sobre manipulação de XML no Oracle.

Ele estava com dificuldades para fazer, bem como para encontrar fontes claras de como realizar esta manipulação.

Com base nisso, resolvi dar uma pesquisada a respeito, e construir um post para ajudá-lo, seguindo nosso “Padrão Dia a dia Oracle de simplicidade”, então vamos lá.

 

1 – Criando a tabela com campo XML

Para manipulação de XML, nas tabelas que vão armazenar os conteúdos já existe um tipo de dados específico para este fim. É o tipo “xmltype”.

Observe abaixo o exemplo de como criar a tabela com um campo deste tipo:



create table t_xml (xml xmltype);

 

2 – Inserindo os dados na tabela com o XML

Para inserção dos dados, mais uma novidade. Existe uma function chamada “XMLType” que “formata” o XML para ser inserido no banco de dados como deve ser. Ele já tem todo tratamento, e inclusive verifica o padrão XML que está sendo inserido, caso tenha algo errado, alguma tag não fechada ou algo semelhante, dá erro na hora do insert, como este abaixo, em que não fechei a tag cliente:



Erro a partir da linha : 5 no comando -
insert into t_xml (xml) values ( XMLType('<cliente><nome>Joao de Souza</nome><dtnasc>01/01/1981</dtnasc><valorcredito>4000</valorcredito>'))
Relatório de erros -
Erro de SQL: ORA-31061: erro de XDB: XML event error
ORA-19202: Ocorreu um erro no processamento XMLLPX-00007: encontrado fim de arquivo inesperado

3 – Fazendo select no campo XML

Para recuperar as informações de um campo XML também tem uma forma específica de fazer. Para este fim, é necessário utilizar uma função chamada “extractValue”. Com ela você consegue informar que tipo de informação do XML deseja retornar, independente do nível de hierarquia do seu XML. A hierarquia é passada de forma semelhante a uma estrutura de diretório, por exemplo, para retornar a data de nascimento do cliente, que está na tag <dtnasc></dtnasc> usamos da seguinte forma: extractValue(xml, ‘/cliente/dtnasc’), abaixo temos o script completo já executado, criando tabela, inserindo os dados e em seguida realizando o select.

 

4 – Script completo executado com create, insert e select



SQL> create table t_xml (xml xmltype);

Table created.

SQL> insert into t_xml (xml) values ( XMLType('<cliente><nome>Joao de Souza</nome><dtnasc>01/01/1981</dtnasc><valorcredito>4000</valorcredito></cliente>'));

1 row created.

SQL>insert into t_xml (xml) values ( XMLType('<cliente><nome>Zefanias Mobiua</nome><dtnasc>01/10/1980</dtnasc><valorcredito>1100</valorcredito></cliente>'));

1 row created.

SQL> insert into t_xml (xml) values ( XMLType('<cliente><nome>Maria da Silva</nome><dtnasc>05/05/1977</dtnasc><valorcredito>5000</valorcredito></cliente>'));

1 row created.


SQL> insert into t_xml (xml) values ( XMLType('<cliente><nome>Joao de Souza</nome><dtnasc>01/01/1981</dtnasc><valorcredito>4000</valorcredito></cliente>'));


1 row created.


SQL> commit;


Commit complete.


SQL> col nome format a30
SQL> col dtnasc format a15
SQL> col valorcredito format a10
SQL> select extractValue(xml, '/cliente/nome') nome,
extractValue(xml, '/cliente/dtnasc') dtnasc,
extractValue(xml, '/cliente/valorcredito') valorcredito
from t_xml 2 3 4 ;
NOME                           DTNASC          VALORCREDITO
------------------------------ --------------- ------------
Gerson Junior                  12/12/1986              1000
Zefanias Mobiua                01/10/1980              1100
Maria da Silva                 05/05/1977              5000
Joao de Souza                  01/01/1981              4000
SQL>

 

É isso então pessoal, espero que este post contribua para seu Dia a Dia Oracle!

 

Agradecimento:

Leitor Zefanias Mobiua que sugeriu o tópico com sua dúvida!

 

Fontes:

http://docs.oracle.com/cd/B19306_01/appdev.102/b14259/xdb03usg.htm#BABDGDJG

http://docs.oracle.com/cd/E11882_01/appdev.112/e23094/xdb04cre.htm#ADXDB0400

http://oracle-base.com/articles/9i/xmltype-datatype.php

http://www.oracle.com/technetwork/database-features/xmldb/overview/oracle-xmldb-11gr2-1974916.html

 

Abraços!!

 

Gerson Júnior

gerson.vasconcelos@gmail.com

 

Cursos Oficiais Oracle com desconto

Fala PessoAll,

Atendendo ao pedido de um leitor do Site, o amigo Lander Poolk S. Herrera estou publicando estas ofertas da Oracle para cursos oficiais.

Tem diversos cursos interessantes e com descontos bem convidativos. Talvez seja a sua chance de fazer um curso oficial pagando menos ou sua chance de conseguir convencer seu chefe a liberar a verba para seu treinamento.

Só lembrando que para tornar-se OCP você precisa obrigatoriamente ter um curso oficial, então, é uma chance de já atender a este requisito.

Este é o link da Oracle sobre os treinamentos, tem tudo detalhado, turmas, descontos, etc.

Noticias sobre Capacitación y Certificación Oracle Database

 

Como dica: Acabei de fazer um treinamento oficial em São Paulo, no Centro de Treinamento En-Sof. O centro é bem interessante, tem uma boa estrutura, salas agradáveis e com bons equipamentos.

Além do local, o que interessa muito em um treinamento é o instrutor. O material a ser seguido e o ambiente do curso é tudo “engessado” pela Oracle, o que vai fazer a diferença é o instrutor que pode ser um simples “Leitor de slides” , ou pode ser um cara de mercado, com conhecimento e boa didática. Portanto, antes de fazer o treinamento, procure saber quem é o instrutor, pegue referências dele e verifique se é uma boa “aquisição”.

 

Abraços a todos!

 

Atc.

Gerson Júnior

gerson.vasconcelos@gmail.com

GUOB Tech Day 2013 – Minhas Impressões.

Olá PessoALL,

Como vocês devem ter visto nos últimos dias, coloquei aqui no site a divulgação do GUOB Tech Day 2013. Esta foi a quarta edição do evento, que mais uma vez uniu diversos profissionais do segmento para um dia de muito conhecimento e networking. O evento é muito bom, e pretendo divulgar mesmo quando não puder ir, pois vale muito a pena! Este ano deu certo.

Vamos as minhas impressões…

O evento foi fantástico mais uma vez, muito bem organizado, credenciamento muito rápido e sem surpresas, coffe brake muito bom, estrutura boa, som muito bom, projetores funcionando e nítidos e os palestrantes nem se fala né? Muito bom!

Gostaria de dar um pequeno overview dos pontos fortes das palestras que assisti. Esses tópicos apontam para MINHA VISÃO, e nada tem a ver com a Oracle, GUOB, etc. Portanto, considerem inclusive que posso ter entendido errado (teve algumas palestras que ouvi sem tradução simultânea e meu “ingrêi” não é dos melhores), e fiquem a vontade pra me corrigir caso notem algo do tipo.

 

Palestra 1: 12C Oracle Multitenant

A palestra foi espetacular, o palestrante é muito bom o Joel Perez. O cara conhece muito, fala muito bem, em espanhol e pausadamente, fácil de entender. O produto 12C é revolucionário realmente, muda vários dos conceitos que conhecemos… vai dar o que falar.

Os pontos fortes mostrados do produto foram 4:

– Consolidação. Agora teremos uma única instance no nosso ambiente (pra quem tem mais de uma) e junto a elas teremos “plugable databases”, ou seja, os bancos de dados agora são uma espécie de “pen drive” que você pluga e despluga no container (instance) que desejar. O ponto forte disso é que economizamos muito em recurso, como sabemos uma instance tem processos background, memória, etc… e isso será reduzido a 1. Então teremos 1 alocação de área de memória, 1 conjunto de processos de background, etc… É um conceito interessante.

– Provisioning. Eles dizem que ficará muito mais fácil a disponibilização de novos ambientes “cópia” de produção. Que o clone vai ser um mero Ctrl+C e Ctrl+V de uma plugable database, simples assim e “sem precisar parar produção”. Ops… esse foi o ponto que o cara falou alto e forte e ainda deu uma paradinha para o “ohhhh”… só que minutos depois anunciou que é preciso que a base de produção esteja em “read-only”… sem parar produção? Quem de nós aqui pode colocar a base em read-only sem impactos? Read-only pra mim, é parar produção! Se é pra ser read-only, coloco meus usuários pra ler do meu DataGuard e paro a produção enquanto faço a cópia dela, não preciso do 12C!

– Upgrade. Num mesmo servidor será possível ter várias versões de containers. Como sabemos, no processo de upgrade o principal é a atualização do dicionário de dados, que é do container, então… se tenho 12.1 e quero migrar pra 12.2, apenas instalo o 12.2 no mesmo servidor e “desplugo” a base X do container 12.1 e plugo ela no outro container 12.2, simples assim! Só que, nem tudo são flores, a recomendação é fazer uma cópia da produção e plugar num outro container… ok… o que isso muda de eu fazer uma cópia da minha produção hoje, e fazer upgrade nela? Caso dê errado, só subir a anterior. Muda nada! A vantagem pra mim seria se eu não precisasse nem me preocupar com cópia da produção, apenas “desplugar” e “plugar”, mas… não é o caso!

– Patch. Segue a mesma linha do upgrade… precisa fazer cópia de produção e plugar a base no container com um novo patch.

É isso… não vi essas vantagens do mundo todo com relação a disponibilidade, mas… sem dúvida ficará muito mais simples. E o gerenciamento parece que vai ficar mais simples. Segundo o palestrante, na 12.2 as cópias poderão ser feitas com a base aberta, e não em read-only… aí sim será uma bela vantagem, vamos esperar!

 

Palestra 2: PL/SQL – Tim Hall

O palestrante é nada mais e nada menos que o dono e mantém o site Oracle-Base, quem do mundo Oracle nunca passou por lá!? Na palestra ele deu dicas fantásticas de PL/SQL que não dá pra mostrar aqui, mas… as que anotei foram para facilitar a identificação de melhorias em códigos PL/SQL com os pacotes: DBMS_UTILITY, principalmente com as procedures: GET_TIME e GET_CPU_TIME. Vale dar uma pesquisada.

 

Palestra 3: Lendas do Oracle – Ricardo Portilho

O palestrante também dispensa apresentações, o cara é muito bom e muito gente boa. A palestra foi sobre as lendas que sempre ouvimos do Oracle. Essa não vou comentar muito porque está disponível nos canais do palestrante. Nerv Informática.

Dos pontos que anotei:

DBMS_ADVANCED, que você consegue reescrever umas query´s… e as coisas que odiamos juntos: BLOB, DBLINK´s e TRIGGERS! kkkkk

 

Palestra 4: 12C: Upgrade Cross-Platform

O palestrante foi novamente o Joel Perez, pelo jeito o cara está mergulhado no 12C, já!

Como sabemos migrar entre plataformas até hoje é meio complexo, Transportable Tablespaces, ExpDP/ImpDP, entre ouros métodos.

No 12C isso muda completamente. O backup será multi-plataforma… fantástico. O processo de migrar de plataforma será um backup de RMAN na origem e um restore no destino! Simples assim! Ou… ainda mais simples e “SEM DOWNTIME”… você poderá fazer um DataGuard de qualquer plataforma para qualquer plataforma! Sensacional! Vai facilitar mesmo! O esboço dos comandos é: “backup for transport database” ou “restore from plataform ‘windows’,’linux’, ‘etc…’ foreign database to…” Se você sabe o destino, converte na hora do backup, se não sabe… converte na hora do restore. Não vejo muito sentido, pois se você está fazendo o backup com esta intenção, deve saber onde vai querer restaurar, mas tem. Estas sim serão novidades interessantes no 12C. Muito bom!

 

Palestra 5: Pré-Requisitos de Instalação – Marcus Vinícius

O palestrante também dispensa apresentações, é mais um brasuca que detona no GUOB Tech Day.

O nome da palestra não era esse, mas… em resumo era isso! Você ignora os prereqs sem mais nem menos? Não faz double check do que o sysadmin falou que fez? É bom baixar e ver a apresentação… Se os prereqs estão lá é porque são usados para alguma coisa, então… deixe eles corretos antes de iniciar sua instalação. Não é dica minha… é da Oracle, ok?!

 

Bom, estas foram as palestras que assisti, todas estão disponíveis em: GUOB – Palestras 2013

Vale a pena baixar para guardar em seu acervo! São conteúdos muito ricos!

 

Além destes pontos, tem duas coisas que acho que pode melhorar no GUOB Tech Day, são elas:

1 – Tradução simultânea: As mocinhas até tentam, mas… o conteúdo é muito técnico e muito rápido. Não tem muito o que fazer com relação ao técnico, elas vão traduzir ao pé da letra mesmo, normal. O problema que encontrei foi que na hora em que elas davam uma “travada” ou que elas iam trocar de tradutora (sim, são duas por sala), elas cortavam uma boa parte da palestra! Algo entre 10 segundos de delay. Imagina 10 segundos do cara falando e você sem ouvir nada. Desisti em todas as vezes da tradução! Acho que é um ponto a melhorar.

2 – Data do evento: Dia dos pais!?! rsrsrs. Não pelo fato do dia dos pais em si, é dia do meu pai todo dia! (parece até que sou emotivo), mas o grande problema é que assim como eu, outras pessoas trabalham e/ou tem clientes no ramo do varejo e como sabemos, o Dia dos Pais é uma data de forte movimento, que geralmente termina em plantões no sábado, impossibilitando a ida ao evento, foi o que aconteceu comigo ano passado. Sei que a Oracle que “define” a data, mas… não custa uma pressãozinha pra tentar mudar isso, vai que dá certo. Uma semana antes ou depois não deve doer muito pra eles.

 

É isso pessoal! Quem não pode ir este ano, programe-se pra ir ano que vem, é um baita evento, tanto com relação a conhecimento, novidades, tendências, experiências quanto a networking, conhecer pessoas novas, rever os amigos, etc. É o caso, por exemplo, dos meus amigos Flávio Soares e Marcus Vinícius (que fez uma palestra muito interessante sobre pré-requisitos das instalações, baixem a apresentação), que pude bater um papo e saber das novidades!

 

Grande abraço a todos, e sintam-se a vontade para comentar, compartilhar, retrucar, enfim… participar!

 

Atc.

Gerson Júnior

gerson.vasconcelos@gmail.com

Erro na Instalação – 10.2.0.1 – OUI-10094

Olá PessoALL,

Ontem tive uma necessidade de instalação do Oracle 10gR2 em um cliente. Isso mesmo, estamos em 07/2013, e precisamos instalar um Oracle 10gR2! rsrs. Deixa eu contar um pouco da história:

O banco de produção é um 9.2.0.6 (acharam que não podia ser pior que o 10gR2 né), rodando em um HP-UX Itanium 64bits e que não tem mais suporte por parte da HP, ou seja, temos que nos virar com o que temos para migrar este banco de 9.2.0.6 urgente! Afinal, não temos mais suporte nem do banco nem da máquina onde ele está instalado. Depois de muitas e muitas tentativas de migração, inclusive usando Golden Gate em que não tivemos sucesso, a opção menos pior encontrada foi expdp e impdp, só que para isso precisávamos estar pelo menos no 10g! Sei que deve estar se perguntando… porque não 11g direto? Lembram que a máquina não tem mais suporte? Pois é, para instalar o 11g neste servidor, mesmo sendo certificado, precisava instalar alguns pacotes, e claro que sem suporte, sem contrato e sem nada, a HP não iria dar de mão beijada estes pacotes para nos ajudar a deixar de usar a plataforma deles! Por isso a escolha do passo a passo foi:

1 – Instalar o Oracle 10GR2, 10.2.0.1.

2 – Aplicar o Patchset 10.2.0.4 e eliminar alguns possíveis bugs.

3 – Migrar o banco 9.2.0.6 para 10.2.0.4.

4 – Fazer expdp paralelizado para extrair os dados.

5 – Fazer impdp no novo, querido e parrudo servidor Linux com Oracle 11gR2!

Então, já no passo 1 encontramos um problema, o erro: OUI-10094.

A instalação ocorria normalmente, todas as configurações eram feitas e dava erro apenas na hora de registrar no inventário.

Pois é, na parte mais simples ocorria o erro.

Pesquisando no Metalink, encontrei uma nota que falava a respeito, em que a Oracle assumia sem nenhum pudor que o instalador do 10.2.0.1, versão base do 10gR2 tinha um “bug” que não conseguia fazer atualização de inventário caso tivessem outros Oracle Home´s  instalados com outros owners na mesma máquina. Por exemplo:

Tenho um Oracle 9.2.0.6 instalado com o owner ora96.

Tenho um Oracle 10gR1 instalado com o owner ora101.

No momento de instalar o Oracle 10gR2 com o owner ora102, ele vai ter que adicionar no inventário esta nova instalação, mas… quem criou o inventário não foi o owner ora102, por isso ocorre o problema, mas é um problema no instalador.

O grande aprendizado que quero passar neste post é sobre a recomendação da Oracle para corrigir o problema, que basicamente foi: “Instale o Oracle 10.2.0.1 com o instalador do 10.2.0.4!”, então, na hora de chamar o runInstaller, usar o executável da versão 10.2.0.4 chamando a instalação do 10.2.0.1. Como fazer isso… assim:


[ora10g@srvhp:/home/ora10g]: cd /ora10g/install/patch_10204/disk1/
[ora10g@srvhp:/home/ora10g]: ./runInstaller FROM_LOCATION="/ora10g/install/10201/disk1/stage/products.xml"

Então, o que fizemos foi ir até a pasta de instalação do Patchset 10.2.0.4 e chamar o instalador dele, só que informando que a instalação deveria pegar os produtos da versão base 10.2.0.1, usando o parâmetro FROM_LOCATION. Interessante não?! Você pode instalar um outro “produto” usando o instalador menos “bugado”.

A conclusão disso pra mim é: Que bom que a Oracle é muito boa de documentação, porque esses probleminhas tem de monte! Só que tudo tá documentado e geralmente tem uma solução de contorno!

Temos então nosso 10gR2 instalado e agora vamos a migração! Caso tenhamos mais novidades, mantenho vocês informados!

 

Abraços a todos.

 

 

Atc.

Gerson Júnior

gerson.vasconcelos@gmail.com

Oracle Tuning – Exportando Estatísticas de Tabelas

Fala PessoAll,

Depois de muito tempo sem postar, estou eu aqui de novo para falar de mais um recurso usado no nosso Diaadia.

Desta vez o problema foi o seguinte:

Temos uma base de produção 9i que está em plena fase de migração para 11g, claro que para que esta migração aconteça, temos que ter a homologação de vários sistemas em 11g, que atualmente rodam na nossa base de produção 9i. Em uma das homologações deste sistema, o analista nos acionou informando que um processo que rodava na base 9i em 10 minutos, já estava a mais de 1 hora rodando na base 11g, sem sucesso.

Vamos as análises…

Passo 1: Identificar que comando estava causando nosso problema, para isso solicitei ao analista rodar a rotina dele habilitando um trace, para tentarmos identificar. Foi solicitado adicionar os seguintes comandos na execução:

begin
--Habilita geracao do trace.
execute immediate('alter session set tracefile_identifier=''TRACE_PROC_LENTA''');
sys.dbms_support.start_trace(true, true);
-- Call the procedure
PROCEDURE_DO_ANALISTA_LENTA;
--Finaliza geracao do trace.
sys.DBMS_SUPPORT.STOP_TRACE;
end;
/

Após concluído o processo, temos que procurar na nossa pasta UDUMP o trace que foi gerado com o identificador “_TRACE_PROC_LENTA”.

Analisando o trace…

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 791 0.02 1.25 0 3 0 0
Execute 72124 9.77 127.63 365 3759 75246 7469
Fetch 81349 109.26 2466.37 229643 14999926 0 75146
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 154264 119.05 2595.27 230008 15003688 75246 82615

Identificamos que o processo rodou em 2595.27 segundos, total!

E temos um comando único, que rodou em 2289.73 segundos. Ficou claro que este é o culpado não??


select COL1, COL2, COL3 from MINHA_TABELA

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 5430 1.11 3.54 0 0 0 0
Fetch 5430 106.61 2286.19 222786 14703253 0 3431
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 10861 107.72 2289.73 222786 14703253 0 3431

Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 214 (OWNER) (recursive depth: 1)

Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS BY INDEX ROWID MINHA_TABELA (cr=7 pr=0 pw=0 time=68 us cost=5 size=33 card=1)
13 INDEX RANGE SCAN MINHA_TABELA_IDX2 (cr=4 pr=0 pw=0 time=40 us cost=4 size=0 card=1)(object id 32870)

Como podemos ver, este select está sendo executado utilizando um índice, o MINHA_TABELA_IDX2. Ótimo, agora vamos comparar este plano de execução, com o plano de execução que temos em produção. Eis o plano de produção:


Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS BY INDEX ROWID MINHA_TABELA (cr=7 pr=0 pw=0 time=68 us cost=5 size=33 card=1)
13 INDEX RANGE SCAN MINHA_TABELA_PK (cr=4 pr=0 pw=0 time=40 us cost=4 size=0 card=1)

Opa…. qual a diferença? Nesta base a minha query acessa os dados pela PK, e não pelo índice! Matamos a parada!!!

Como resolver?

A base onde a homologação estava sendo feita era uma base 11g criada com uma cópia antiga de produção, que não vinha sendo coletada estatística, que estava sendo constantemente alterada pelos testes e que não estava 100%. Para coletar estatísticas novamente desta tabela, seria mais complicado e demorado, pois a tabela tem 667.000.000 de linhas, claro, o teste tem que ser agora!!!!

Lembramos então que tinhamos uma cópia fresquinha da base de produção, que tinha sido recém migrada para 11g, ou seja, estava em 11g, mas tinha as estatísticas certinhas de produção, onde a query estava rápida.

A solução encontrada foi: Exportar as estatísticas desta tabela.

Então, vamos lá…

Passo 1: Criar uma tabela de estatísticas na base origem, para receber as estatísticas atuais da tabela:


SQL> exec SYS.DBMS_STATS.CREATE_STAT_TABLE(ownname => 'DBAGABOS', stattab => 'TLISTENER_STATS');
Procedimento PL/SQL concluÝdo com sucesso.
SQL>

Passo 2: Exportar as estatísticas atuais da tabela na base de origem, para a tabela de esatísticas que você criou:


SQL> exec DBMS_STATS.EXPORT_TABLE_STATS(ownname => 'DBAGABOS', tabname => 'TLISTENER', stattab => 'TLISTENER_STATS', cascade => true);
Procedimento PL/SQL concluÝdo com sucesso.
SQL>

Passo 3: Exportar esta tabela gerada…


C:UsersGersonJr>exp dbagabos@orcl tables=TLISTENER_STATS file=dump_stats.dmp
Export: Release 10.2.0.3.0 - Production on Seg Ago 1 19:23:58 2011
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Senha:
Conectado a: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning, OLAP and Data Mining options
ExportaþÒo executada no conjunto de caracteres de WE8MSWIN1252 e no conjunto de caracteres de AL16UTF16 NCHAR
Sobre exportar tabelas especificadas ... via Caminho Convencional ...
. . exportando tabela TLISTENER_STATS 113 linhas exportadas
ExportaþÒo encerrada com sucesso, sem advertÛncias.
C:UsersGersonJr>

Passo 4: Importar a tabela de estatísticas que você exportou, no banco de destino…


C:UsersGersonJr>imp dbagabos@orcl_destino tables=TLISTENER_STATS file=dump_stats.dmp
Import: Release 10.2.0.3.0 - Production on Seg Ago 1 19:24:58 2011
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Senha:
Conectado a: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning, OLAP and Data Mining options
Arquivo de exportaþÒo criado por EXPORT:V10.02.01 via caminho convencional
AdvertÛncia: os objetos foram exportados por DBAGABOS; nÒo por vocÛ
importaþÒo realizada nos conjuntos de caracteres WE8MSWIN1252 e NCHAR AL16UTF16
. importando objetos de DBAGABOS para DBAGABOS
. importando objetos de DBAGABOS para DBAGABOS
. . importando table "TLISTENER_STATS" 113 linhas importadas
ImportaþÒo encerrada com sucesso, sem advertÛncias.
C:UsersGersonJr>

Passo 5: Importar as estatísticas para a tabela, lendo da tabela de estatísticas que você importou.

exec DBMS_STATS.IMPORT_TABLE_STATS(ownname => 'DBAGABOS', tabname => ‘TLISTENER’, stattab => ‘TLISTENER_STATS’, cascade => true, no_invalidate => true);

E agora é só você testar seu plano de execução e verificar se na base nova a query está se comportando da mesma forma que na base antiga.

Algumas considerações:
1 – O problema ocorreu na base 11g, porém para criar o post refiz os comandos na base instalada no meu PC, que é 10.2.0.3, como podem ver nos comandos acima.

2 – Estes passos não querem dizer que há uma garantia 100% da sua query ficar igual a sua base de origem, lembre-se que em performance existem inúmeros outros pontos que são verificados para o banco montar um plano de execução.

3 – A idéia deste post é mostrar este recurso de export/import de estatísticas, que é simples e rápido de fazer, e pode ajudar-nos em vários casos.

Qualquer coisa, estou à disposição para dúvidas e/ou sugestões!

Grande abraço.

Atc.
Gerson Júnior
gerson.vasconcelos@gmail.com

Dica EXPDP – COMPRESSION

Fala PessoAll,

Estive fazendo um EXPDP de uma base de aproximadamente 360Gb.


nohup expdp userid=myusr/mypwd directory=DIR_EXPORT_SCHEMA dumpfile=exp_MS_MSI_18032011.dmp logfile=exp_MS_MSI_18032011.log schemas=MS,MSI status=300

Iniciei o export, e o directory DIR_EXPORT_SCHEMA estava em uma partição que tinha 112Gb livre, imaginei que o export ocorreria sem problemas, porém… de repente… erro no log, ao verificar, disco estava em 100% de uso. Ou seja, ele gerou um arquivo de 112Gb!

Então, lembrei que no bom e velho EXP tinha um parâmetro COMPRESS e decidi ver como era agora no novo EXPDP. Verificando o Help (expdp help=y), encontrei o parâmetro COMPRESSION e passei a utilizá-lo no meu comando, ficando assim:


nohup expdp userid=myusr/mypwd directory=DIR_EXPORT_SCHEMA dumpfile=exp_MS_MSI_18032011.dmp logfile=exp_MS_MSI_18032011.log schemas=MS,MSI compression=ALL status=300

Depois da conclusão do processo, fui ver o tamanho do arquivo e tive um baita surpresa! O dump inteiro ficou com 31Gb! Ou seja, sem compressão, chegamos em 112Gb e estourou o disco, com a compressão ficou em 31Gb.

Fica a dica, caso alguém tenha alguma restrição de espaço, manda bala com o COMPRESSION do EXPDP que realmente funciona, e a compressão é BEM significativa!

Abraços.

Atc.
Gerson Júnior
gerson.vasconcelos@gmail.com

Alternativa InitCap. Upper e Lower no lugar certo.

Fala PessoALL,

Hoje falaremos de manipulação/formatação de strings, com o uso da boa e velha função InitCap do Oracle.
Acho que muitos de nós já nos deparamos com este tipo de problema, temos no nosso banco, uma determinada descrição gravada da forma que o usuário achar mais bonito! Ou seja, sem ter um padrão para gravação. Para gravar a frase: “Este blog é uma beleza”, por exemplo, podemos ter de várias formas:

– Este blog é uma beleza
– ESTE BLOG É UMA BELEZA
– EsTe BlOg É uMa BeLeZa (vai que o usuário é internetês)

Entre muitas outras formas. Porém na hora de fazermos um relatório, gostaríamos muitas vezes que nosso relatório mantenha um padrão de exibição da descrição, fica no mínimo estranho que tenhamos uma frase maíuscula, outra minúscula, outra mesclada, etc… para isso o Oracle nos dá uma função chamada InitCap.

Esta função nos dá a possibilidade de padronizar a nossa descrição, ela coloca maiúscula todas as primeiras letras das palavras da frase, por exemplo:

– Este Blog É Uma Beleza

Só que este ainda não é o padrão que utilizamos para escrever, apenas as primeiras letras da primeira palavra da frase é que são maiúsculas. Todas as demais são minúsculas, ficando a frase assim:

-Este blog é uma beleza

Bem mais bonito não??

Pensando nesse problema, vamos deixar de blábláblá e vamos a prática!

Eu desenvolvi uma função, a pedido do meu amigo Marcos Castro, que faz exatamente isso que queremos, ela só coloca maíuscula a primeira letra da primeira palavra de uma nova frase, ou seja, o que vem depois do ponto, como costumamos fazer no nosso dia-a-dia, como mostrado no exemplo acima.

Segue a função:


create or replace function initcapmc(p_str varchar2) return varchar2 is
v_carac_anterior varchar2(1);
v_carac_atual varchar2(1);
v_retorno varchar2(32767);
begin
--Atribui o primeiro caractere como maiúsculo.
v_retorno := upper(substr(p_str,1,1));

--Varre a string a partir da segunda posição
for i in 2..length(p_str) loop
--Recupera o caractere que está sendo analisado
v_carac_atual := substr(p_str,i,1);

--Se o caractere analisado anteriormente foi um ponto, vai colocar maiúsculo
if(v_carac_anterior = '.') then
v_retorno := v_retorno || upper(v_carac_atual);
else
v_retorno := v_retorno || lower(v_carac_atual);
end if;

--Atribui o caractere já processado como sendo o anterior, para a proxima execucao. Ignora espaco.
if(trim(v_carac_atual) is not null) then
v_carac_anterior := v_carac_atual;
end if;
end loop;

return v_retorno;

end;

Espero que gostem… em caso de bugs, favor informar.

Atc.
Gerson Júnior
(gerson.vasconcelos@gmail.com)

Oracle – Sinônimos públicos (public synonyms). Quando devo usar?

Fala PessoALL,

Depois de muito tempo sem escrever, vamos nós de novo!

Tenho me deparado sempre com dúvidas de desenvolvedores quanto ao uso de sinônimos públicos. Devemos usar? Não devemos? Cria pra todos os objetos? Não cria? Vamos tentar de uma vez por todas desvendar esse mistério de public synonym no Oracle.

Bom, sinônimos, como bem sabemos são palavras que tem o mesmo significado… isso no português! No Oracle, sinônimo é um pouco diferente, porém sendo um pouco igual! Confuso não? Rs. Vamos simplificar!

No Oracle o sinônimo público (public synonym) é um objeto de banco, cujo dono é PUBLIC (ou seja, todo mundo) que “aponta” para um outro objeto de um determinado schema. Como se fosse uma espécie de link. Por exemplo:

Imagine que você tem uma tabela no schema DONOSIS chamada MINHATABELA. Caso algum usuário que não seja DONOSIS deseje executar um select nesta tabela, você faz o seguinte comando: select * from donosis.minhatabela, mas e se eu não quiser colocar o dono do objeto na frente? Seja para que meus usuários não saibam quem é o dono dos objetos (questões de segurança), seja para que eu simplifique a codificação? Aí eu uso o sinônimo público! Eu crio um sinônimo púbico chamado MINHATABELA que aponta para o objeto de banco: DONOSIS.MINHATABELA. O código para criação é:

create or replace public synonym MINHATABELA for DONOSIS.MINHATABELA;

Após a criação deste sinônimo público, qualquer usuário do banco que executar o select select * from MINHATABELA; conseguirá de forma transparente acessar a tabela MINHATABELA do schema DONOSIS sem nem saber que ela se encontra neste schema! Simples não?

Isso pode ser utilizado para qualquer objeto de banco, como: Views, Procedures, Functions, Packages, Tables, etc.

Claro que para que o acesso ao objeto seja concluído, o usuário que está acessando tem que possuir privilégio no objeto de destino. Ou seja, mesmo com sinônimo público, os privilégios que foram concedidos no objeto de destino continuam funcionando normalmente.

Vantagens?
Simplicidade de codificação (não precisa colocar o nome do dono do objeto na frente).
Transparência de propriedade (não se sabe quem é o dono do objeto).
Simples modificação de objetos (você pode mudar o dono dos objetos, sem impacto algum).

Quando não usar?
Quando o objeto só será utilizado pelo próprio dono. Por exemplo: Se nossa tabela MINHATABELA fosse utilizada apenas por objetos do schema DONOSIS, não tinhamos a menor necessidade de ter um sinônimo, o objeto sendo do próprio schema, não precisamos colocar o schema na frente!

Erros mais comuns:
ORA-01775 loop chain of synonyms – Este erro ocorre geralmente quando ocorre algum problema com o objeto destino que o sinônimo aponta, por exemplo: Se for uma procedure que está inválida; Se for uma tabela que não existe; algo do tipo!

É isso pessoal, espero que tenha ficado claro como funciona e para que serve os sinônimos públicos (public synonym). Por enquanto é só!

Qualquer coisa, basta entrar em contato.

Atc.
Gerson Júnior
gerson.vasconcelos@gmail.com

Função de grupo para multiplicar, SUM -> MULT

Fala pessoal,

Recebi um email de um leitor solicitando uma solução para que fosse desenvolvida uma função semelhante ao SUM, já nativo do banco de dados Oracle, só que fizesse multiplicação e não soma, como o SUM faz atualmente!

Por exemplo:

Tabela: FATORIAL
Campo: VALOR

Valor
5
6
3
2
3

Portanto, se usarmos o SUM, teriamos um resultado assim: 5 + 6 + 3 + 2 + 3 = 19
O pretendido é: 5 * 6 * 3 * 2 * 3 = 540

A sugestão que dei foi: Criar uma função própria que faça a multiplicação dos valores. A implementação/testes ficou assim:


SQL> --Cria tabela
SQL> create table fatorial(campo1 number, valor number);
Tabela criada.
SQL> --Insere valores
SQL> insert into fatorial values (1,2);
1 linha criada.
SQL> insert into fatorial values (1,3);
1 linha criada.
SQL> insert into fatorial values (2,4);
1 linha criada.
SQL> insert into fatorial values (2,4);
1 linha criada.
SQL>

Em seguida criamos a seguinte function:


SQL> create or replace function mult_vals(p_filtro number) return number is
2 v_retorno number;
3 begin
4 v_retorno := 0;
5 for i in (select valor from fatorial where campo1 = p_filtro)
6 loop
7 if (v_retorno = 0) then
8 v_retorno := 1;
9 end if;
10 v_retorno := v_retorno*i.valor;
11 end loop;
12 return v_retorno;
13 end;
14 /
FunþÒo criada.
SQL>

E depois é só testar:


SQL> select campo1, mult_vals(campo1)
2 from fatorial
3 group by campo1;
CAMPO1 MULT_VALS(CAMPO1)
---------- -----------------
1 6
2 16
SQL>

Funcionou como uma luva não?

É isso, o que não tem nativo a gente faz!
Neste caso fiz algo bem específico, só pra atender a necessidade que nosso leitor precisava, mas podemos pensar em algo mais genérico, se necessário! Usando SQL Dinâmico, passando nome do campo a ser multiplicado e nome da tabela! Fica a sugestão!

Agradecendo ao nosso leitor Rodrigo Vieira pela solicitação!!

Grande abraço, espero que gostem.