<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dia a dia Oracle &#187; dicas</title>
	<atom:link href="http://www.diaadiaoracle.com.br/category/dicas/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.diaadiaoracle.com.br</link>
	<description></description>
	<lastBuildDate>Mon, 01 Aug 2011 22:36:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Oracle Tuning &#8211; Exportando Estatísticas de Tabelas</title>
		<link>http://www.diaadiaoracle.com.br/2011/08/01/oracle-tuning-exportando-estatisticas-de-tabelas/</link>
		<comments>http://www.diaadiaoracle.com.br/2011/08/01/oracle-tuning-exportando-estatisticas-de-tabelas/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 22:36:23 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[procedures]]></category>
		<category><![CDATA[query]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=98</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>Fala PessoAll,</p>
<p>Depois de muito tempo sem postar, estou eu aqui de novo para falar de mais um recurso usado no nosso Diaadia.</p>
<p>Desta vez o problema foi o seguinte:</p>
<p>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.</p>
<p>Vamos as análises&#8230;</p>
<p>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:</p>
<p><code>begin<br />
   --Habilita geracao do trace.<br />
   execute immediate('alter session set tracefile_identifier=''TRACE_PROC_LENTA''');<br />
   sys.dbms_support.start_trace(true, true);<br />
   -- Call the procedure<br />
   PROCEDURE_DO_ANALISTA_LENTA;<br />
   --Finaliza geracao do trace.<br />
   sys.DBMS_SUPPORT.STOP_TRACE;<br />
end;<br />
/</code></p>
<p>Após concluído o processo, temos que procurar na nossa pasta UDUMP o trace que foi gerado com o identificador &#8220;_TRACE_PROC_LENTA&#8221;.</p>
<p>Analisando o trace&#8230;<br />
<code><br />
call     count       cpu    elapsed       disk      query    current        rows<br />
------- ------  -------- ---------- ---------- ---------- ----------  ----------<br />
Parse      791      0.02       1.25          0          3          0           0<br />
Execute  72124      9.77     127.63        365       3759      75246        7469<br />
Fetch    81349    109.26    2466.37     229643   14999926          0       75146<br />
------- ------  -------- ---------- ---------- ---------- ----------  ----------<br />
total   154264    119.05    2595.27     230008   15003688      75246       82615<br />
</code></p>
<p>Identificamos que o processo rodou em 2595.27 segundos, total!</p>
<p>E temos um comando único, que rodou em 2289.73 segundos. Ficou claro que este é o culpado não??</p>
<p><code><br />
select COL1, COL2, COL3 from MINHA_TABELA</p>
<p>call     count       cpu    elapsed       disk      query    current        rows<br />
------- ------  -------- ---------- ---------- ---------- ----------  ----------<br />
Parse        1      0.00       0.00          0          0          0           0<br />
Execute   5430      1.11       3.54          0          0          0           0<br />
Fetch     5430    106.61    2286.19     222786   14703253          0        3431<br />
------- ------  -------- ---------- ---------- ---------- ----------  ----------<br />
total    10861    107.72    2289.73     222786   14703253          0        3431</p>
<p>Misses in library cache during parse: 0<br />
Optimizer mode: ALL_ROWS<br />
Parsing user id: 214  (OWNER)   (recursive depth: 1)</p>
<p>Rows     Row Source Operation<br />
-------  ---------------------------------------------------<br />
      1  TABLE ACCESS BY INDEX ROWID MINHA_TABELA (cr=7 pr=0 pw=0 time=68 us cost=5 size=33 card=1)<br />
     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)<br />
</code></p>
<p>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: </p>
<p><code><br />
Rows     Row Source Operation<br />
-------  ---------------------------------------------------<br />
      1  TABLE ACCESS BY INDEX ROWID MINHA_TABELA (cr=7 pr=0 pw=0 time=68 us cost=5 size=33 card=1)<br />
     13   INDEX RANGE SCAN MINHA_TABELA_PK (cr=4 pr=0 pw=0 time=40 us cost=4 size=0 card=1)<br />
</code></p>
<p>Opa&#8230;. qual a diferença? Nesta base a minha query acessa os dados pela PK, e não pelo índice! Matamos a parada!!! </p>
<p>Como resolver?</p>
<p>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!!!!</p>
<p>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.</p>
<p>A solução encontrada foi: <b>Exportar as estatísticas desta tabela</b>.</p>
<p>Então, vamos lá&#8230;</p>
<p>Passo 1: Criar uma tabela de estatísticas na base origem, para receber as estatísticas atuais da tabela:</p>
<p><code><br />
SQL> exec SYS.DBMS_STATS.CREATE_STAT_TABLE(ownname => 'DBAGABOS', stattab => 'TLISTENER_STATS');<br />
Procedimento PL/SQL concluÝdo com sucesso.<br />
SQL><br />
</code></p>
<p>Passo 2: Exportar as estatísticas atuais da tabela na base de origem, para a tabela de esatísticas que você criou:</p>
<p><code><br />
SQL> exec DBMS_STATS.EXPORT_TABLE_STATS(ownname => 'DBAGABOS', tabname => 'TLISTENER', stattab => 'TLISTENER_STATS', cascade => true);<br />
Procedimento PL/SQL concluÝdo com sucesso.<br />
SQL><br />
</code></p>
<p>Passo 3: Exportar esta tabela gerada&#8230;</p>
<p><code><br />
C:\Users\GersonJr>exp dbagabos@orcl tables=TLISTENER_STATS file=dump_stats.dmp<br />
Export: Release 10.2.0.3.0 - Production on Seg Ago 1 19:23:58 2011<br />
Copyright (c) 1982, 2005, Oracle.  All rights reserved.<br />
Senha:<br />
Conectado a: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production<br />
With the Partitioning, OLAP and Data Mining options<br />
ExportaþÒo executada no conjunto de caracteres de WE8MSWIN1252  e no conjunto de caracteres de AL16UTF16 NCHAR<br />
Sobre exportar tabelas especificadas ... via Caminho Convencional ...<br />
. . exportando tabela                TLISTENER_STATS          113 linhas exportadas<br />
ExportaþÒo encerrada com sucesso, sem advertÛncias.<br />
C:\Users\GersonJr><br />
</code></p>
<p>Passo 4: Importar a tabela de estatísticas que você exportou, no banco de destino&#8230;</p>
<p><code><br />
C:\Users\GersonJr>imp dbagabos@orcl_destino tables=TLISTENER_STATS file=dump_stats.dmp<br />
Import: Release 10.2.0.3.0 - Production on Seg Ago 1 19:24:58 2011<br />
Copyright (c) 1982, 2005, Oracle.  All rights reserved.<br />
Senha:<br />
Conectado a: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production<br />
With the Partitioning, OLAP and Data Mining options<br />
Arquivo de exportaþÒo criado por EXPORT:V10.02.01 via caminho convencional<br />
AdvertÛncia: os objetos foram exportados por DBAGABOS; nÒo por vocÛ<br />
importaþÒo realizada nos conjuntos de caracteres WE8MSWIN1252 e NCHAR AL16UTF16<br />
. importando objetos de DBAGABOS para DBAGABOS<br />
. importando objetos de DBAGABOS para DBAGABOS<br />
. . importando table              "TLISTENER_STATS"          113 linhas importadas<br />
ImportaþÒo encerrada com sucesso, sem advertÛncias.<br />
C:\Users\GersonJr><br />
</code></p>
<p>Passo 5: Importar as estatísticas para a tabela, lendo da tabela de estatísticas que você importou.<br />
<code><br />
exec DBMS_STATS.IMPORT_TABLE_STATS(ownname => 'DBAGABOS', tabname => ‘TLISTENER’, stattab => ‘TLISTENER_STATS’, cascade => true, no_invalidate => true);<br />
</code></p>
<p>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.</p>
<p>Algumas considerações:<br />
1 &#8211; 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.</p>
<p>2 &#8211; 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.</p>
<p>3 &#8211; 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.</p>
<p>Qualquer coisa, estou à disposição para dúvidas e/ou sugestões!</p>
<p>Grande abraço.</p>
<p>Atc.<br />
Gerson Júnior<br />
gerson.vasconcelos@gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2011/08/01/oracle-tuning-exportando-estatisticas-de-tabelas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dica EXPDP &#8211; COMPRESSION</title>
		<link>http://www.diaadiaoracle.com.br/2011/03/21/dica-expdp-compression/</link>
		<comments>http://www.diaadiaoracle.com.br/2011/03/21/dica-expdp-compression/#comments</comments>
		<pubDate>Mon, 21 Mar 2011 13:57:28 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[11g]]></category>
		<category><![CDATA[exp]]></category>
		<category><![CDATA[expdp]]></category>
		<category><![CDATA[export]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=92</guid>
		<description><![CDATA[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&#8230; de repente&#8230; erro no log, ao verificar, disco estava em 100% de [...]]]></description>
			<content:encoded><![CDATA[<p>Fala PessoAll,</p>
<p>Estive fazendo um <strong>EXPDP </strong> de uma base de aproximadamente 360Gb. </p>
<p><code><br />
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<br />
</code></p>
<p>Iniciei o <strong>export</strong>, e o directory DIR_EXPORT_SCHEMA estava em uma partição que tinha 112Gb livre, imaginei que o export ocorreria sem problemas, porém&#8230; de repente&#8230; erro no log, ao verificar, disco estava em 100% de uso. Ou seja, ele gerou um arquivo de 112Gb!</p>
<p>Então, lembrei que no bom e velho <strong>EXP </strong> tinha um parâmetro <strong>COMPRESS </strong>e decidi ver como era agora no novo <strong>EXPDP</strong>. Verificando o Help (<code>expdp help=y</code>), encontrei o parâmetro COMPRESSION e passei a utilizá-lo no meu comando, ficando assim:</p>
<p><code><br />
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<br />
</code></p>
<p>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. </p>
<p>Fica a dica, caso alguém tenha alguma restrição de espaço, manda bala com o <strong>COMPRESSION</strong> do <strong>EXPDP</strong> que realmente funciona, e a compressão é BEM significativa!</p>
<p>Abraços.</p>
<p>Atc.<br />
Gerson Júnior<br />
gerson.vasconcelos@gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2011/03/21/dica-expdp-compression/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Alternativa InitCap. Upper e Lower no lugar certo.</title>
		<link>http://www.diaadiaoracle.com.br/2010/09/22/alternativa-initcap-upper-e-lower-no-lugar-certo/</link>
		<comments>http://www.diaadiaoracle.com.br/2010/09/22/alternativa-initcap-upper-e-lower-no-lugar-certo/#comments</comments>
		<pubDate>Wed, 22 Sep 2010 19:40:53 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[initcap]]></category>
		<category><![CDATA[lower]]></category>
		<category><![CDATA[lowercase]]></category>
		<category><![CDATA[maiuscula]]></category>
		<category><![CDATA[minuscula]]></category>
		<category><![CDATA[upper]]></category>
		<category><![CDATA[uppercase]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=88</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>Fala PessoALL,</p>
<p>Hoje falaremos de manipulação/formatação de strings, com o uso da boa e velha função <b><code>InitCap</code></b> do <b>Oracle</b>.<br />
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: &#8220;Este blog é uma beleza&#8221;, por exemplo, podemos ter de várias formas:</p>
<p>- Este blog é uma beleza<br />
- ESTE BLOG É UMA BELEZA<br />
- EsTe BlOg É uMa BeLeZa (vai que o usuário é internetês)</p>
<p>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&#8230; para isso o <b>Oracle</b> nos dá uma função chamada <b><code>InitCap</code></b>.</p>
<p>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:</p>
<p>- Este Blog É Uma Beleza</p>
<p>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:</p>
<p>-Este blog é uma beleza</p>
<p>Bem mais bonito não??</p>
<p>Pensando nesse problema, vamos deixar de blábláblá e vamos a prática! </p>
<p>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.</p>
<p>Segue a função:</p>
<p><code><br />
create or replace function initcapmc(p_str varchar2) return varchar2 is<br />
   v_carac_anterior varchar2(1);<br />
   v_carac_atual    varchar2(1);<br />
   v_retorno        varchar2(32767);<br />
begin<br />
   --Atribui o primeiro caractere como maiúsculo.<br />
   v_retorno := upper(substr(p_str,1,1));</p>
<p>   --Varre a string a partir da segunda posição<br />
   for i in 2..length(p_str) loop<br />
      --Recupera o caractere que está sendo analisado<br />
      v_carac_atual := substr(p_str,i,1);</p>
<p>      --Se o caractere analisado anteriormente foi um ponto, vai colocar maiúsculo<br />
      if(v_carac_anterior = '.') then<br />
         v_retorno := v_retorno || upper(v_carac_atual);<br />
      else<br />
         v_retorno := v_retorno || lower(v_carac_atual);<br />
      end if;</p>
<p>      --Atribui o caractere já processado como sendo o anterior, para a proxima execucao. Ignora espaco.<br />
      if(trim(v_carac_atual) is not null) then<br />
         v_carac_anterior := v_carac_atual;<br />
      end if;<br />
   end loop;</p>
<p>   return v_retorno;</p>
<p>end; </p>
<p></code></p>
<p>Espero que gostem&#8230; em caso de bugs, favor informar.</p>
<p>Atc.<br />
Gerson Júnior<br />
(gerson.vasconcelos@gmail.com)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2010/09/22/alternativa-initcap-upper-e-lower-no-lugar-certo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Oracle &#8211; Sinônimos públicos (public synonyms). Quando devo usar?</title>
		<link>http://www.diaadiaoracle.com.br/2010/09/20/oracle-sinonimos-publicos-public-synonyms-quando-devo-usar/</link>
		<comments>http://www.diaadiaoracle.com.br/2010/09/20/oracle-sinonimos-publicos-public-synonyms-quando-devo-usar/#comments</comments>
		<pubDate>Mon, 20 Sep 2010 19:31:21 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[procedures]]></category>
		<category><![CDATA[select]]></category>
		<category><![CDATA[public synonym]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=81</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>Fala PessoALL,</p>
<p>Depois de muito tempo sem escrever, vamos nós de novo!</p>
<p>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 <b>public synonym</b> no <b>Oracle</b>.</p>
<p>Bom, sinônimos, como bem sabemos são palavras que tem o mesmo significado&#8230; isso no português! No Oracle, sinônimo é um pouco diferente, porém sendo um pouco igual! Confuso não? Rs. Vamos simplificar!</p>
<p>No Oracle o sinônimo público (<b>public synonym</b>) é um objeto de banco, cujo dono é PUBLIC (ou seja, todo mundo) que &#8220;aponta&#8221; para um outro objeto de um determinado schema. Como se fosse uma espécie de link. Por exemplo:</p>
<p>Imagine que você tem uma tabela no schema <code>DONOSIS</code> chamada <code>MINHATABELA</code>. Caso algum usuário que não seja <code>DONOSIS</code> deseje executar um select nesta tabela, você faz o seguinte comando: <code>select * from donosis.minhatabela</code>, 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 <code>MINHATABELA</code> que aponta para o objeto de banco: <code>DONOSIS.MINHATABELA</code>. O código para criação é:</p>
<p><code>create or replace public synonym MINHATABELA for DONOSIS.MINHATABELA;</code></p>
<p>Após a criação deste sinônimo público, qualquer usuário do banco que executar o select <code>select * from MINHATABELA;</code> conseguirá de forma transparente acessar a tabela <code>MINHATABELA</code> do schema <code>DONOSIS</code> sem nem saber que ela se encontra neste schema! Simples não?</p>
<p>Isso pode ser utilizado para qualquer objeto de banco, como: Views, Procedures, Functions, Packages, Tables, etc.</p>
<p>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.</p>
<p><b>Vantagens?</b><br />
Simplicidade de codificação (não precisa colocar o nome do dono do objeto na frente).<br />
Transparência de propriedade (não se sabe quem é o dono do objeto).<br />
Simples modificação de objetos (você pode mudar o dono dos objetos, sem impacto algum).</p>
<p><b>Quando não usar?</b><br />
Quando o objeto só será utilizado pelo próprio dono. Por exemplo: Se nossa tabela <code>MINHATABELA</code> fosse utilizada apenas por objetos do schema <code>DONOSIS</code>, 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!</p>
<p><b>Erros mais comuns:</b><br />
<b>ORA-01775</b> loop chain of synonyms &#8211; 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!</p>
<p>É isso pessoal, espero que tenha ficado claro como funciona e para que serve os sinônimos públicos (<b>public synonym</b>). Por enquanto é só!</p>
<p>Qualquer coisa, basta entrar em contato. </p>
<p>Atc.<br />
Gerson Júnior<br />
gerson.vasconcelos@gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2010/09/20/oracle-sinonimos-publicos-public-synonyms-quando-devo-usar/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Função de grupo para multiplicar, SUM -&gt; MULT</title>
		<link>http://www.diaadiaoracle.com.br/2010/04/08/funcao-de-grupo-para-multiplicar-sum-mult/</link>
		<comments>http://www.diaadiaoracle.com.br/2010/04/08/funcao-de-grupo-para-multiplicar-sum-mult/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 17:33:36 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[aula oracle]]></category>
		<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[dinamico]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[functions group]]></category>
		<category><![CDATA[group by]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[select]]></category>
		<category><![CDATA[sum]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=78</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>Fala pessoal,</p>
<p>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!</p>
<p>Por exemplo:</p>
<p>Tabela: FATORIAL<br />
Campo: VALOR</p>
<p>Valor<br />
     5<br />
     6<br />
     3<br />
     2<br />
     3</p>
<p>Portanto, se usarmos o SUM, teriamos um resultado assim: 5 + 6 + 3 + 2 + 3 = 19<br />
O pretendido é: 5 * 6 * 3 * 2 * 3 = 540</p>
<p>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:</p>
<p><code><br />
SQL> --Cria tabela<br />
SQL> create table fatorial(campo1 number, valor number);<br />
Tabela criada.<br />
SQL> --Insere valores<br />
SQL> insert into fatorial values (1,2);<br />
1 linha criada.<br />
SQL> insert into fatorial values (1,3);<br />
1 linha criada.<br />
SQL> insert into fatorial values (2,4);<br />
1 linha criada.<br />
SQL> insert into fatorial values (2,4);<br />
1 linha criada.<br />
SQL><br />
</code></p>
<p>Em seguida criamos a seguinte function:</p>
<p><code><br />
SQL> create or replace function mult_vals(p_filtro number) return number is<br />
  2     v_retorno number;<br />
  3  begin<br />
  4     v_retorno := 0;<br />
  5     for i in (select valor from fatorial where campo1 = p_filtro)<br />
  6     loop<br />
  7        if (v_retorno = 0) then<br />
  8           v_retorno := 1;<br />
  9        end if;<br />
 10        v_retorno := v_retorno*i.valor;<br />
 11     end loop;<br />
 12     return v_retorno;<br />
 13  end;<br />
 14  /<br />
FunþÒo criada.<br />
SQL><br />
</code></p>
<p>E depois é só testar:</p>
<p><code><br />
SQL> select campo1, mult_vals(campo1)<br />
  2    from fatorial<br />
  3   group by campo1;<br />
    CAMPO1 MULT_VALS(CAMPO1)<br />
---------- -----------------<br />
         1                 6<br />
         2                16<br />
SQL><br />
</code></p>
<p>Funcionou como uma luva não?</p>
<p>É isso, o que não tem nativo a gente faz!<br />
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!</p>
<p>Agradecendo ao nosso leitor Rodrigo Vieira pela solicitação!!</p>
<p>Grande abraço, espero que gostem.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2010/04/08/funcao-de-grupo-para-multiplicar-sum-mult/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Guida de referência de SQL Básico</title>
		<link>http://www.diaadiaoracle.com.br/2010/03/08/guida-de-referencia-de-sql-basico/</link>
		<comments>http://www.diaadiaoracle.com.br/2010/03/08/guida-de-referencia-de-sql-basico/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 20:01:49 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[aula oracle]]></category>
		<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[curso oracle]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[distinct]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[oracle 10g]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[select]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[basico]]></category>
		<category><![CDATA[comando sql]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=74</guid>
		<description><![CDATA[Fala pessoAll, Com a contribuição do nosso amigo e leitor Robson Cristovão, está aí um guia básico de SQL que pode ser bastante útil para quem está começando no mundo SQL e tem algumas dúvidas quanto ao uso e sitaxe de alguns comandos SQL! Fica a dica! AND &#124; OR: SELECT nome_coluna(s) FROM nome_tabela WHERE [...]]]></description>
			<content:encoded><![CDATA[<p>Fala pessoAll,</p>
<p>Com a contribuição do nosso amigo e leitor <strong>Robson Cristovão</strong>, está aí um guia básico de SQL que pode ser bastante útil para quem está começando no mundo SQL e tem algumas dúvidas quanto ao uso e sitaxe de alguns comandos SQL! Fica a dica! </p>
<p><code>AND | OR:<br />
	SELECT nome_coluna(s)<br />
	FROM    nome_tabela<br />
	WHERE condiçao<br />
	AND | OR condiçao<br />
</code></p>
<p><code>ALTER TABLE (add coluna):<br />
	ALTER TABLE nome_tabela<br />
	ADD nome_coluna datatype<br />
</code></p>
<p><code>ALTER TABLE (drop column):<br />
	ALTER TABLE nome_tabela<br />
	DROP COLUMN nome_coluna<br />
</code></p>
<p><code>AS (alias for column):<br />
	SELECT nome_coluna AS coluna_apelido<br />
	FROM nome_tabela<br />
</code></p>
<p><code>AS (alias for table):<br />
	SELECT nome_coluna<br />
	FROM nome_tabela  AS tabela_apelido<br />
</code></p>
<p><code>BETWEEN:<br />
	SELECT nome_coluna(s)<br />
	FROM nome_tabela<br />
	WHERE nome_coluna<br />
	BETWEEN valor1 AND valor2<br />
</code></p>
<p><code>CREATE (database):<br />
	CREATE DATABASE nome_base_de_dados<br />
</code></p>
<p><code>CREATE (index):<br />
	CREATE INDEX nome_indice<br />
	ON nome_tabela (nome_coluna)<br />
</code></p>
<p><code>CREATE (table):<br />
	CREATE TABLE nome_tabela(<br />
	nome_coluna1 tipo_dado,<br />
	nome_coluna2 tipo_dado,...)<br />
</code></p>
<p><code>CREATE (unique index):<br />
	CREATE UNIQUE INDEX nome_indice<br />
	ON nome_tabela (nome_coluna)<br />
</code></p>
<p><code>CREATE (view):<br />
	CREATE VIEW nome_da_view AS<br />
	SELECT nome_coluna(s)<br />
	FROM nome_tabela<br />
	WHERE condiçao<br />
</code></p>
<p><code>DELETE:<br />
	DELETE FROM nome_tabela<br />
OU<br />
	DELETE FROM nome_tabela<br />
	WHERE condiçao<br />
</code></p>
<p><code>DROP (database):<br />
	DROP DATABASE nome_base_de_dados<br />
</code></p>
<p><code>DROP (index):<br />
	DROP INDEX nome_tabela.nome_indice<br />
</code></p>
<p><code>DROP (table):<br />
	DROP TABLE nome_tabela<br />
</code></p>
<p><code>GROUP BY:<br />
	SELECT nome_coluna1,SUM(nome_coluna2)<br />
	FROM nome_tabela<br />
	GROUP BY nome_coluna1<br />
</code></p>
<p><code>HAVING:<br />
	SELECT nome_coluna1,SUM(nome_coluna2)<br />
	FROM nome_tabela<br />
	GROUP BY nome_coluna1<br />
	HAVING SUM(nome_coluna2) valor_da_condiçao<br />
</code></p>
<p><code>IN:<br />
	SELECT nome_coluna(s)<br />
	FROM nome_tabela<br />
	WHERE nome_coluna<br />
	IN (valor1,valor2,..)<br />
</code></p>
<p><code>INSERT:<br />
	INSERT INTO nome_tabela<br />
	VALUES (valor1, valor2,....)<br />
OU<br />
	INSERT INTO nome_tabela<br />
	(nome_coluna1, nome_coluna2,...)<br />
	VALUES (valor1, valor2,....)<br />
</code></p>
<p><code>LIKE:<br />
	SELECT nome_coluna(s)<br />
	FROM nome_tabela<br />
	WHERE nome_coluna<br />
	LIKE padrao<br />
</code></p>
<p><code>ORDER BY:<br />
	SELECT nome_coluna(s)<br />
	FROM nome_tabela<br />
	ORDER BY nome_coluna [ASC | DESC<br />
</code></p>
<p><code>SELECT:<br />
	SELECT nome_coluna(s)<br />
	FROM nome_tabela<br />
</code></p>
<p><code>SELECT (all):<br />
	SELECT * FROM nome_tabela<br />
</code></p>
<p><code>SELECT (distinct):<br />
	SELECT DISTINCT nome_coluna(s)<br />
	FROM nome_tabela<br />
</code></p>
<p><code>SELECT (into - usado para criar cópias auxiliares das tabelas):<br />
	SELECT * INTO new_nome_tabela<br />
	FROM original_nome_tabela<br />
OU<br />
	SELECT nome_coluna(s)<br />
	INTO new_nome_tabela<br />
	FROM original_nome_tabela<br />
</code></p>
<p><code>TRUNCATE:<br />
	TRUNCATE TABLE nome_tabela<br />
</code></p>
<p><code>UPDATE:<br />
	UPDATE nome_tabela<br />
	SET nome_coluna=novo_valor<br />
	[, nome_coluna=novo_valor]<br />
	WHERE nome_coluna = algum_valor<br />
</code></p>
<p><code>WHERE:<br />
	SELECT nome_coluna(s)<br />
	FROM nome_tabela<br />
	WHERE condiçao<br />
</code></p>
<p>Espero que gostem.</p>
<p>Atc.<br />
Gerson Júnior<br />
gerson.vasconcelos@gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2010/03/08/guida-de-referencia-de-sql-basico/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dica: Como descobrir quem referencia uma coluna?</title>
		<link>http://www.diaadiaoracle.com.br/2010/02/11/dica-como-descobrir-quem-referencia-uma-coluna/</link>
		<comments>http://www.diaadiaoracle.com.br/2010/02/11/dica-como-descobrir-quem-referencia-uma-coluna/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 14:46:26 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[distinct]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[select]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[dictionary]]></category>
		<category><![CDATA[foreign key]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=72</guid>
		<description><![CDATA[Fala PessoAll, A dica de hoje é a respeito do seguinte&#8230; Muitas vezes temos a necessidade de fazer algumas alterações nas nossas tabelas, nosso modelo, etc. E aí precisamos levantar quais tabelas recerenciam uma determinada tabela ou coluna, quais as filhas dessas colunas, quais as foreign key que fazem referência a elas e etc. Aí, [...]]]></description>
			<content:encoded><![CDATA[<p>Fala PessoAll,</p>
<p>A dica de hoje é a respeito do seguinte&#8230;</p>
<p>Muitas vezes temos a necessidade de fazer algumas alterações nas nossas tabelas, nosso modelo, etc. E aí precisamos levantar quais tabelas recerenciam uma determinada tabela ou coluna, quais as filhas dessas colunas, quais as <b>foreign key</b> que fazem referência a elas e etc.</p>
<p>Aí, podemos usar o seguinte <b>select</b>:</p>
<p><code><br />
select distinct c.table_name<br />
  from dba_constraints  c,<br />
       dba_cons_columns cc<br />
 where c.constraint_type = 'R'<br />
   and cc.owner           = c.owner<br />
   and cc.constraint_name = c.r_constraint_name<br />
   and cc.owner           = &#038;SCHEMA<br />
   and cc.table_name      = &#038;TABELA<br />
   and cc.column_name     = &#038;COLUNA<br />
</code></p>
<p>Claro que temos que mudar os parâmetros &#038;SCHEMA, &#038;TABELA e &#038;COLUNA, para recuperar as tabelas que são filhas da tabela que você deseja.</p>
<p>Exemplo fica melhor não? Vamos lá:</p>
<p>Eu preciso descobrir quais as tabelas que fazem referência a alguma coluna da tabela <code>SOURCE</code>, para tal fazemos o seguinte <b>select</b>:</p>
<p><code><br />
SQL> select DISTINCT C.TABLE_NAME<br />
  2    from dba_constraints  c,<br />
  3         dba_cons_columns cc<br />
  4   where c.constraint_type = 'R'<br />
  5     and cc.owner           = c.owner<br />
  6     and cc.constraint_name = c.r_constraint_name<br />
  7     and cc.owner           = 'ORABUGIT'<br />
  8     and cc.table_name      = 'SOURCES'<br />
  9  /<br />
TABLE_NAME<br />
------------------------------<br />
PEOPLE_EQUIPS<br />
</code></p>
<p>Como podemos ver, obtemos como resposta a tabela <code>PEOPLE_EQUIPS</code>, portanto podemos ver que nesta tabela tem alguma coluna que referencia através de <b>foreign key</b> uma coluna da tabela <code>SOURCE</code>.</p>
<p>Espero que a dica seja útil!!</p>
<p>Abraços.</p>
<p>Atc.<br />
Gerson Júnior<br />
gerson.vasconcelos@gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2010/02/11/dica-como-descobrir-quem-referencia-uma-coluna/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Potência / Expoentes em SQL e PL/SQL &#8211; Oracle</title>
		<link>http://www.diaadiaoracle.com.br/2010/02/08/potencia-expoentes-em-sql-e-plsql-oracle/</link>
		<comments>http://www.diaadiaoracle.com.br/2010/02/08/potencia-expoentes-em-sql-e-plsql-oracle/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 17:08:32 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[oracle 10g]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[dica sql]]></category>
		<category><![CDATA[expoente]]></category>
		<category><![CDATA[potencia]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=69</guid>
		<description><![CDATA[Fala Pessoal, Hoje vai mais uma dica de SQL e PL/SQL. Até o dia de hoje, eu nunca tinha necessitado usar expoente no SQL / PL/SQL, nunca tinha pego nenhum problema em desenvolvimento que precisasse ser usado potência, expoente e tal. Porém, hoje uma amiga desenvolvedora, Leilah, precisou dessa funcionalidade e aí discutimos um pouco [...]]]></description>
			<content:encoded><![CDATA[<p>Fala Pessoal,</p>
<p>Hoje vai mais uma dica  de SQL e PL/SQL.</p>
<p>Até o dia de hoje, eu nunca tinha necessitado usar expoente no SQL / PL/SQL, nunca tinha pego nenhum problema em desenvolvimento que precisasse ser usado potência, expoente e tal. </p>
<p>Porém, hoje uma amiga desenvolvedora, Leilah, precisou dessa funcionalidade e aí discutimos um pouco sobre o assunto. Descobri portanto, que no Oracle, não precisamos fazer muita conta e nem usar sintaxes esquisitas para usar potência e elevar um número a uma determinada potência, basta usarmos a função <b>POWER</b>, isso mesmo, funciona assim:</p>
<p>Exemplo SQL:<br />
<code><br />
SQL> select power(2,3) from dual;<br />
POWER(2,3)<br />
----------<br />
         8<br />
</code><br />
Neste exemplo, temos 2 elevado a 3, que nos dá 8 como resultado&#8230;</p>
<p>Exemplo PL/SQL:<br />
<code><br />
SQL> declare<br />
  2     v_num number;<br />
  3  begin<br />
  4     v_num := power(2,3);<br />
  5     dbms_output.put_line('O numero 2 elevado a 3 é: '||to_char(v_num));<br />
  6  end;<br />
  7  /<br />
O numero 2 elevado a 3 é: 8<br />
Procedimento PL/SQL concluÝdo com sucesso.<br />
</code></p>
<p>Pronto pessoal, fica aí a dica de utilização de potência em PL/SQL.</p>
<p>Espero que gostem.</p>
<p>Grande abraço.</p>
<p>Atc.<br />
Gerson Júnior<br />
gerson.vasconcelos@gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2010/02/08/potencia-expoentes-em-sql-e-plsql-oracle/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Dica de SQL &#8211; Primeiro sábado do mês seguinte</title>
		<link>http://www.diaadiaoracle.com.br/2010/02/01/dica-de-sql-primeiro-sabado-do-mes-seguinte/</link>
		<comments>http://www.diaadiaoracle.com.br/2010/02/01/dica-de-sql-primeiro-sabado-do-mes-seguinte/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 17:21:14 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[automatizar tarefas.]]></category>
		<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[job]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[dica sql]]></category>
		<category><![CDATA[recupera primeiro sabado]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=65</guid>
		<description><![CDATA[Fala PessoAll, Recebi um email do amigo Vitor Ugo sobre uma solicitação que ele havia recebido para criação de um Job. Até aí moleza, como podemos ver no post: Job no Oracle criar um Job é fácil! Só que este Job tem uma particularidade, ele deve rodar apenas no primeiro sábado de cada mês. Com [...]]]></description>
			<content:encoded><![CDATA[<p>Fala PessoAll,</p>
<p>Recebi um email do amigo Vitor Ugo sobre uma solicitação que ele havia recebido para criação de um Job. </p>
<p>Até aí moleza, como podemos ver no post: <a href="http://www.diaadiaoracle.com.br/2009/06/10/job-no-oracle/" target="top">Job no Oracle</a> criar um Job é fácil! Só que este Job tem uma particularidade, ele deve rodar apenas no primeiro sábado de cada mês.</p>
<p>Com isso, fiz a dica para Vitor, dele colocar o job para executar todo dia, e antes de chamar a procedure do job fazer um teste e identificar se era o primeiro sábado, se sim, beleza roda a procedure, senão, não faz nada! Funcionaria, porém não é uma solução das mais bonitas, porque mesmo sem fazer nada, o job executaria todos os dias.</p>
<p>Foi então que o Vitor desenvolveu um select, que recupera o primeiro sábado do mês seguinte, e resolveu todos os problemas.</p>
<p>Segue o select desenvolvido por Vitor:</p>
<p><code><br />
select LEAST(NEXT_DAY(ADD_MONTHS(trunc(sysdate,'MM')+(8/24),1)-1,7),<br />
             next_day(ADD_MONTHS(trunc(sysdate,'MM')+(8/24),1),7)) from dual;<br />
</code></p>
<p>Neste select o &#8220;7&#8243; indica que é um sábado, caso desejem outro dia da semana, basta que vocês alterem esse número para o dia desejado!</p>
<p>É isso, fica aí a dica. Espero que gostem</p>
<p>Abraço a todos.</p>
<p>Atc.<br />
Gerson Júnior<br />
gerson.vasconcelos@gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2010/02/01/dica-de-sql-primeiro-sabado-do-mes-seguinte/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Oracle &#8211; SQL TRACE &#8211; TKPROF</title>
		<link>http://www.diaadiaoracle.com.br/2009/12/22/oracle-sql-trace-tkprof/</link>
		<comments>http://www.diaadiaoracle.com.br/2009/12/22/oracle-sql-trace-tkprof/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 12:02:19 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[sql trace]]></category>
		<category><![CDATA[tkprof]]></category>
		<category><![CDATA[trace]]></category>
		<category><![CDATA[tunning]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=49</guid>
		<description><![CDATA[Fala PessoAll, Estamos aqui novamente para compartilhar mais uma experiência. Dessa vez com algo bastante básico para quem quer se especializar em performance de aplicações, que é o meu caso!! Em alguns momentos na nossa vida de DBA nos deparamos com processos que são um tanto quanto complexos de serem analisados, por exemplo: Uma procedure [...]]]></description>
			<content:encoded><![CDATA[<p>Fala  PessoAll,</p>
<p>Estamos aqui novamente para compartilhar mais uma experiência.</p>
<p>Dessa vez com algo bastante básico para quem quer se especializar em performance de aplicações, que é o meu caso!!</p>
<p>Em alguns momentos na nossa vida de DBA nos deparamos com processos que são um tanto quanto complexos de serem analisados, por exemplo: Uma procedure que demora muito ou uma query que demora demais para retornar ou um procedimento inteiro que tem todas as querys otimizadas mas demora muito entre outras coisas. Para que possamos analisar estes tipos de problemas, temos um grande aliado que é o SQL_TRACE, ele vai gerar uma espécie de “relatório” com todas as query´s envolvidas no processamento, e nos mostrar o que cada query fez, o plano de execução de cada uma, quanto tempo demorou para rodar, quanto de CPU consumiu, quantas vezes foi executada, isso nos dá uma visão exata do que está ocorrendo, podendo ser até um erro de lógica na aplicação, onde por exemplo, devido a um erro uma determinada query é executada milhares de vezes sem necessidade.</p>
<p>Hoje vou mostrar como fazemos para gerar um trace de uma determinada operação no banco e como formatar este trace de forma que possamos ler e entender o passo a passo da execução. Vamos lá!</p>
<p>O primeiro passo é alterar a sessão que o processo vai rodar para que o trace seja gerado, isso pode ser feito com o comando:</p>
<p>ALTER SESSION SET SQL_TRACE=TRUE;</p>
<p>Após este commando, podemos executar a nossa rotina lenta, que um arquivo será gerado com o que esta rotina fez.</p>
<p>Begin<br />
   Nossa_Rotina_Lenta(1,4,4);<br />
End;</p>
<p>Após a conclusão do processamento, devemos ir até o local onde foi gerado o arquivo, no meu caso, o arquivo é gerado no caminho: {ORACLE_BASE}\admin\negraod\udump</p>
<p>Se você tentar abrir o arquivo gerado, possivelmente não vai conseguir entender nada! Para que nosso arquivo fique legível, vamos usar um utilitário chamado TKPROF. Esse utilitário tem como objetivo interpretar o trace e deixar ele num formato legível.</p>
<p>O uso do TKPROF é da seguinte forma: tkprof trace.trc arquivo_saida.txt explain=usuário/senha@banco</p>
<p>Depois deste comando executado, no seu arquivo de saída, terá um conteúdo parecido com este:</p>
<p>********************************************************************************<br />
count    = Numero de vezes que o procedimento foi executado<br />
cpu      = Tempo em segundos executando pelo CPU<br />
elapsed  = Tem em segundos para execução do procedimento<br />
disk     = Numero de leituras físicas no disco<br />
rows     = Numero de linhas processadas pelo comando<br />
********************************************************************************</p>
<p> SELECT COUNT(*)<br />
 FROM   dual</p>
<p>call    count    cpu elapsed    disk   query current     rows<br />
&#8212;&#8212;- &#8212;&#8211;  &#8212;&#8211; &#8212;&#8212;- &#8212;&#8212;- &#8212;&#8212;- &#8212;&#8212;-  &#8212;&#8212;-<br />
Parse       1   0.02    0.02       0       0       0        0<br />
Execute     1   0.00    0.00       0       0       0        0<br />
Fetch       2   0.00    0.00       0       1       4        1<br />
&#8212;&#8212;- &#8212;&#8211;  &#8212;&#8211; &#8212;&#8212;- &#8212;&#8212;- &#8212;&#8212;- &#8212;&#8212;-  &#8212;&#8212;-<br />
total       4   0.02    0.02       0       1       4        1</p>
<p>Misses in library cache during parse: 1<br />
Optimizer goal: CHOOSE<br />
Parsing user id: 121  </p>
<p>Rows     Row Source Operation<br />
&#8212;&#8212;-  &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
      1  SORT AGGREGATE<br />
      1   TABLE ACCESS FULL DUAL</p>
<p>Neste exemplo, conseguimos ler e ver o que aconteceu com a query, além do plano de execução que ela utilizou para executar.</p>
<p>Depois disso é analisar as query´s mais complexas e atacar na mudança delas, em muitos casos é necessário a mudança da lógica da rotina, para que se possa ganhar alguma performance!</p>
<p>É isso pessoal. Espero que ajude vocês!</p>
<p>Atc.<br />
Gerson Júnior<br />
gerson.vasconcelos@gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2009/12/22/oracle-sql-trace-tkprof/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

