<?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; desenvolvimento</title>
	<atom:link href="http://www.diaadiaoracle.com.br/category/desenvolvimento/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.diaadiaoracle.com.br</link>
	<description></description>
	<lastBuildDate>Thu, 08 Apr 2010 17:33:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<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
     [...]]]></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 condiçao
	AND [...]]]></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í, podemos usar o [...]]]></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>0</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 sobre [...]]]></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 isso, fiz [...]]]></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 que demora [...]]]></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>
		<item>
		<title>Validando Digito Verificador Inscrição Estadual Bahia (BA)</title>
		<link>http://www.diaadiaoracle.com.br/2009/10/22/validando-digito-verificador-inscricao-estadual-bahia-ba/</link>
		<comments>http://www.diaadiaoracle.com.br/2009/10/22/validando-digito-verificador-inscricao-estadual-bahia-ba/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 12:15: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[function]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[oracle 10g]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[digito verificador IE]]></category>
		<category><![CDATA[inscricao estadual]]></category>
		<category><![CDATA[validar dig verificador]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=39</guid>
		<description><![CDATA[Fala PessoAll,
Bom, como toda e boa pessoa normal, de vez em quando bate a saudade das épocas de desenvolvimento, de quebrar cabeça para fazer alguns códigos &#8220;ninja&#8221; pra resolver alguns problemas do nosso Dia a Dia (Oracle, rsrs).
Otem me deparei com a demanda de um amigo, precisando fazer uma validação do dígito da Inscrição estadual [...]]]></description>
			<content:encoded><![CDATA[<p>Fala PessoAll,</p>
<p>Bom, como toda e boa pessoa normal, de vez em quando bate a saudade das épocas de desenvolvimento, de quebrar cabeça para fazer alguns códigos &#8220;ninja&#8221; pra resolver alguns problemas do nosso Dia a Dia (Oracle, rsrs).</p>
<p>Otem me deparei com a demanda de um amigo, precisando fazer uma validação do dígito da Inscrição estadual da Bahia, em PL/SQL. Vamos lá!</p>
<p>Primeiro passo: Pesquisar como se faz a validação do dígito verificador da inscrição estadual da BAHIA!! BAHIA!! Ninguém melhor que a Sefaz/BA pra me dizer isso. Então, fui no site da SEFAZ/BA e achei como fazer a validação, depois foi só cair no PL/SQL de cabeça e colocar pra funcionar. A página que diz como deve ser feita a validação é: <a href="http://www.sefaz.ba.gov.br/contribuinte/informacoes_fiscais/doc_fiscal/calculodv.htm" target="top">http://www.sefaz.ba.gov.br/contribuinte/informacoes_fiscais/doc_fiscal/calculodv.htm</a>.</p>
<p>Segue abaixo a function utilizada para fazer esta validação. Essa function retorna &#8216;S&#8217; caso esteja OK e &#8216;N&#8217; caso não seja validado o dígito verificador.</p>
<p><code><br />
create or replace function valida_dig_inscest_BA(pInscEstadual varchar2) return varchar2 is<br />
   v_IE varchar2(10);</p>
<p>   idig1 number;<br />
   idig2 number;</p>
<p>   iRes1 number;<br />
   iRes2 number;</p>
<p>   cBase1 number;<br />
   cBase2 number;<br />
begin<br />
   v_IE := rtrim(replace(replace(replace(pInscEstadual, '.', ''), '-', ''), '/', ''));</p>
<p>   if length(v_IE) <> 8 then<br />
      return('N');<br />
   end if;</p>
<p>   iRes1  := 0;<br />
   iRes2  := 0;</p>
<p>   cBase1 := substr(v_IE, 1, 6);<br />
   iDig1  := substr(v_IE, 7, 1);<br />
   iDig2  := substr(v_IE, 8, 1);</p>
<p>   --Se o primeiro dígito for um dos testados, modulo 10, senao, modulo 11<br />
   if(substr(cBase1, 1, 1) in (0, 1, 2, 3, 4, 5, 8)) then<br />
      --Faz um loop de 7 até 2...<br />
      for i in reverse 2 .. 7 loop<br />
         --Verifica se o numero encontrado é válido.<br />
         if instr('0123456789', SubStr(cBase1, (7-i)+1, 1)) > 0 Then<br />
            --Sendo válido, já soma com a multiplicação pelo indice.<br />
            ires2 := ires2 + (SubStr(cBase1, (7-i)+1, 1) * i);<br />
         else<br />
            return('N');<br />
         end if;<br />
      end loop;</p>
<p>      --Recupera o resto do calculo realizado por 10<br />
      ires2 := mod(ires2, 10);</p>
<p>      --Se for 0, o digito é zero.<br />
      if(ires2 = 0) then<br />
         ires2 := 0;<br />
      --Se não for zero, subtrai o valor de 10<br />
      else<br />
         ires2 := 10 - ires2;<br />
      end if;</p>
<p>      --O numero para o calculo do primeiro digito, é os 6 primeiros + o digito 2<br />
      cBase2 := cBase1||ires2;</p>
<p>      --Faz um loop de 8 até 2...<br />
      for i in reverse 2 .. 8 loop<br />
         --Verifica se o numero encontrado é válido.<br />
         if instr('0123456789', SubStr(cBase2, (8-i)+1, 1)) > 0 Then<br />
            --Sendo válido, já soma com a multiplicação pelo indice.<br />
            ires1 := ires1 + (SubStr(cBase2, (8-i)+1, 1) * i);<br />
         else<br />
            return('N');<br />
         end if;<br />
      end loop;</p>
<p>      --Recupera o resto do calculo realizado por 10<br />
      ires1 := mod(ires1, 10);</p>
<p>      --Se for 0, o digito é zero.<br />
      if(ires1 = 0) then<br />
         ires1 := 0;<br />
      --Se não for zero, subtrai o valor de 10<br />
      else<br />
         ires1 := 10 - ires1;<br />
      end if;</p>
<p>      --Se resultado 1 e 2 iguais a digitos 1 e 2, é válido<br />
      if(ires1 = idig1 and ires2 = idig2) then<br />
         return('S');<br />
      else<br />
         return('N');<br />
      end if;<br />
   --Se começa com 6, 7 ou 9<br />
   else<br />
      --Faz um loop de 7 até 2...<br />
      for i in reverse 2 .. 7 loop<br />
         --Verifica se o numero encontrado é válido.<br />
         if instr('0123456789', SubStr(cBase1, (7-i)+1, 1)) > 0 Then<br />
            --Sendo válido, já soma com a multiplicação pelo indice.<br />
            ires2 := ires2 + (SubStr(cBase1, (7-i)+1, 1) * i);<br />
         else<br />
            return('N');<br />
         end if;<br />
      end loop;</p>
<p>      --Recupera o resto do calculo realizado por 11<br />
      ires2 := mod(ires2, 11);</p>
<p>      --Se for 0, o digito é zero.<br />
      if(ires2 = 0) then<br />
         ires2 := 0;<br />
      --Se não for zero, subtrai o valor de 11<br />
      else<br />
         ires2 := 11 - ires2;<br />
      end if;</p>
<p>      --O numero para o calculo do primeiro digito, é os 6 primeiros + o digito 2<br />
      cBase2 := cBase1||ires2;</p>
<p>      --Faz um loop de 8 até 2...<br />
      for i in reverse 2 .. 8 loop<br />
         --Verifica se o numero encontrado é válido.<br />
         if instr('0123456789', SubStr(cBase2, (8-i)+1, 1)) > 0 Then<br />
            --Sendo válido, já soma com a multiplicação pelo indice.<br />
            ires1 := ires1 + (SubStr(cBase2, (8-i)+1, 1) * i);<br />
         else<br />
            return('N');<br />
         end if;<br />
      end loop;</p>
<p>      --Recupera o resto do calculo realizado por 10<br />
      ires1 := mod(ires1, 11);</p>
<p>      --Se for 0, o digito é zero.<br />
      if(ires1 = 0) then<br />
         ires1 := 0;<br />
      --Se não for zero, subtrai o valor de 10<br />
      else<br />
         ires1 := 11 - ires1;<br />
      end if;</p>
<p>      if(ires1 = idig1 and ires2 = idig2) then<br />
         return('S');<br />
      else<br />
         return('N');<br />
      end if;<br />
   end if;<br />
end;<br />
</code></p>
<p>É isso aí gente, espero que seja útil.</p>
<p>Atc.<br />
Gerson Júnior<br />
gerson.vasconcelos@gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2009/10/22/validando-digito-verificador-inscricao-estadual-bahia-ba/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JOB no ORACLE &#8211; Definindo a periodicidade. (INTERVAL)</title>
		<link>http://www.diaadiaoracle.com.br/2009/10/20/job-no-oracle-definindo-a-periodicidade-interval/</link>
		<comments>http://www.diaadiaoracle.com.br/2009/10/20/job-no-oracle-definindo-a-periodicidade-interval/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 19:05:32 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[automatizar tarefas.]]></category>
		<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[job]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[jobs]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=36</guid>
		<description><![CDATA[Fala PessoALL,
Bom, atendendo à dica do amigo Alessandro Varela (http://blogdovarela.com.br) hoje falarei sobre: Como definir corretamente a periodicidade da execução dos seus Job&#8217;s! Complica não? É nada!! Vamos lá!
Espero que todos tenham lido o post que fiz falando sobre Job&#8217;s, caso não tenha lido, ainda dá tempo, basta ler o post Jobs no Oracle.
Bom, quando [...]]]></description>
			<content:encoded><![CDATA[<p>Fala PessoALL,</p>
<p>Bom, atendendo à dica do amigo Alessandro Varela (http://blogdovarela.com.br) hoje falarei sobre: Como definir corretamente a periodicidade da execução dos seus Job&#8217;s! Complica não? É nada!! Vamos lá!</p>
<p>Espero que todos tenham lido o post que fiz falando sobre Job&#8217;s, caso não tenha lido, ainda dá tempo, basta ler o post <a href="http://www.diaadiaoracle.com.br/2009/06/10/job-no-oracle/" target="top">Jobs no Oracle</a>.</p>
<p>Bom, quando fazemos a criação de um Job, é porque temos a necessidade que uma determinada tarefa seja executada de tempos em tempos, e para isso geralmente precisamos definir um intervalo para que o Job seja executado novamente. Por exemplo: Quero que meu Job rode a cada hora, quero que meu Job rode todo dia de 23:00, quero que meu job rode a cada 5 minutos, e assim por diante. Só que no momento de fazer esta parametrização é quando começa a confusão, pois, as pessoas esquecem de que o Job vai rodar sozinho e ele é quem tem que definir a próxma execução! Para simplificar isso, vamos lá!</p>
<p>Todo mundo lembra no post anterior que eu falei que para criar um Job usamos a package <code>DBMS_JOB</code> e a procedure <code>DBMS_JOB.SUBMIT(...)</code>, certo? Pois é, nesta procedure, um dos parâmetros que é passado é um tal de <code>INTERVAL</code>, ou seja, o intervalo entre cada execução do seu Job. É aqui que mora o X (xis) da questão! É neste parametro que vamos informar de quanto em quando tempo nosso Job vai rodar.</p>
<p>O que tem que ser considerado aqui, é que o Job será executado automaticamente (essa é a razão do seu existir) e é justamente por isso que rola a confusão, quando este parâmetro for usado já não estaremos mais na data &#8220;agora&#8221;, estaremos na data de execução do Job, sei lá, 23:00! E aí o banco vai usar este parâmetro <code>INTERVAL</code> para setar o campo NEXT_DATE, que é a próxima data em que o Job será executado, ou seja você tem que levar em consideração que o banco sempre vai usar sysdate para calcular este valor.</p>
<p>Como é de rotina, vamos para os exemplos que tudo vai ficar mais claro.<br />
Exemplos mais comuns:</p>
<p>Job para rodar de hora em hora:<br />
Interval -&gt; &#8217;sysdate + 1/24&#8242;<br />
Ou seja, se este Job rodar dia 25/10/2009 às 14:00, quando for somada 1 hora, teremos 15:00 como NEXT_DATE.</p>
<p>Job para rodar a cada 5 minutos.<br />
Interval -&gt; &#8217;sysdate + 5/1440&#8242;<br />
Ou seja, se este Job rodar dia 25/10/2009 às 14:00, quando for somado 5 minutos (1/1440), teremos 14:05 como NEXT_DATE.</p>
<p>Job para rodar uma vez por mês:<br />
Interval -&gt; &#8216;add_months(sysdate, 1)&#8217;<br />
Ou seja, se executar dia 25/10/2009, aplicando este valor acima, teriamos 25/11/2009 como NEXT_DATE.</p>
<p>Esse foi um dos casos mais estranhos, pedido através do blog pra mim&#8230;<br />
Job para rodar em um dia específico a cada ano e numa determinada hora:<br />
&#8216;add_months(to_date(to_char(sysdate, &#8221;DD/MM/YYYY&#8221;)||&#8221; 05:00&#8221;, &#8221;DD/MM/YYYY HH24:MI&#8221;), 12)&#8217;<br />
Ou seja, se o job rodar dia 25/10/2009 as 15:00, e aplicarmos esta fórmula aí, teremos 25/10/2010 05:00 como NEXT_DATE.</p>
<p>Uma dica legal para você fazer esta fórmula que será o NEXT_DATE do seu Job é dar <code>select</code> em <code>sysdate</code> usando a <code>dual</code>. Que eu creio ser o que o banco faz na hora de rodar o Job.</p>
<p>Por exemplo:<br />
Se executarmos o comando:<br />
<code>select sysdate, sysdate + 1/24 from dual</code><br />
Vamos obter como retorno:<br />
<code><br />
sysdate                      sysdate + 1/24<br />
20/10/2009 15:55:35	20/10/2009 16:55:35<br />
</code></p>
<p>Isso aí nos dá a hora atual e a hora atual somado 1 hora. Assim você monta seu NEXT_DATE facilmente!</p>
<p>É isso pessoal, espero que tenha ficado claro e que daqui pra frente seja mais fácil montar seus Jobs para as mais diversas necesidades.</p>
<p>Qualquer coisa, estamos por aqui!</p>
<p>Atc.<br />
Gerson Júnior<br />
gerson.vasconcelos@gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2009/10/20/job-no-oracle-definindo-a-periodicidade-interval/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Cursor no Oracle- PL/SQL</title>
		<link>http://www.diaadiaoracle.com.br/2009/03/19/cursor-no-oracle-plsql/</link>
		<comments>http://www.diaadiaoracle.com.br/2009/03/19/cursor-no-oracle-plsql/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 20:05:00 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[cursores]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[loop]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[pl/sql]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=4</guid>
		<description><![CDATA[Fala PessoAll,
Bom, verificando com o pessoal de algumas listas de e-mails sobre Oracle e um pessoal que trabalha aqui comigo no desenvolvimento Oracle, verifiquei que existem algumas dúvidas quanto a utilização de Cursores no desenvolvimento PL/SQL. Por este motivo, estarei mostrando aqui algumas formas de utilizarmos cursores e explicando algumas vantagens e desvantagens, claro&#8230; No [...]]]></description>
			<content:encoded><![CDATA[<p>Fala PessoAll,</p>
<p>Bom, verificando com o pessoal de algumas listas de e-mails sobre Oracle e um pessoal que trabalha aqui comigo no desenvolvimento Oracle, verifiquei que existem algumas dúvidas quanto a utilização de Cursores no desenvolvimento PL/SQL. Por este motivo, estarei mostrando aqui algumas formas de utilizarmos cursores e explicando algumas vantagens e desvantagens, claro&#8230; No meu ponto de vista!</p>
<p>Para os exemplos que irei fazer, vou usar uma tabela simples de clientes que pode ser criada e populada com o script abaixo:</p>
<p><code><br />
create table clientes(codigo number(5), nome varchar2(50), cpf number(11));<br />
insert into clientes (codigo, nome, cpf) values (1, 'CLIENTE 1 DA SILVA', 00100200301);<br />
insert into clientes (codigo, nome, cpf) values (2, 'CLIENTE 2 DA SILVA', 00200200302);<br />
insert into clientes (codigo, nome, cpf) values (3, 'CLIENTE 3 DA SILVA', 00300200303);<br />
insert into clientes (codigo, nome, cpf) values (4, 'CLIENTE 4 DA SILVA', 00400200304);<br />
insert into clientes (codigo, nome, cpf) values (5, 'CLIENTE 5 DA SILVA', 00500200305);<br />
insert into clientes (codigo, nome, cpf) values (6, 'CLIENTE 6 DA SILVA', 00600200306);<br />
insert into clientes (codigo, nome, cpf) values (7, 'CLIENTE 7 DA SILVA', 00700200307);<br />
commit;<br />
</code></p>
<p>A primeira forma de utilizarmos um cursor é declarando ele na cláusula <code>Declare</code> do seu bloco PL/SQL. Esta utilização tem o nome de <strong>Cursor Explícito</strong></p>
<p>Vamos ao exemplo de procedure que usa este recurso:</p>
<p><code><br />
create or replace procedure entendendoCursor is<br />
--Declarando o cursor<br />
Cursor C_RetornaCliente is<br />
Select codigo,<br />
nome,<br />
cpf<br />
from clientes;</code></p>
<p>&#8211;Declarando variável que receberá cada linha retornada do cursor<br />
rCli C_RetornaCliente%rowtype;</p>
<p>Begin<br />
&#8211;Comando para abrir o cursor<br />
Open C_RetornaCliente;</p>
<p>&#8211;Faz um laço para percorrer todas as linhas do cursor<br />
Loop<br />
&#8211;Lê a linha encontrada e coloca os valores na variável rCli.<br />
Fetch C_RetornaCliente into rCli;<br />
&#8211;&#8221;Avisa&#8221; para a rotina que caso não encontre mais nada, pode sair do laço.<br />
Exit when C_RetornaCliente%notFound;</p>
<p>&#8211;Exibe na tela as informações do cliente<br />
dbms_output.put_line(&#8216;Código: &#8216;||rCli.codigo||&#8217; Nome: &#8216;||rCli.nome||&#8217; CPF: &#8216;||rCli.cpf);<br />
End loop;</p>
<p>&#8211;Fecha o cursor.<br />
Close C_RetornaCliente;<br />
End;</p>
<p>Este exemplo percorre os registros encontrados no cursor e os exibe na tela.</p>
<p>Bom, na minha opinião esta é a forma mais &#8220;chata&#8221; de fazer, pois como pode ser observado, precisamos criar um cursor lá na área onde declaramos as variáveis que serão utilizadas no programa, depois temos que declarar uma outra variável que será do tipo <code>rowtype</code> do cursor (<strong>rowtype</strong> é quando você cria uma variável que irá receber os valores de acordo com o que for retornado no cursor, e acessamos os campos depois assim: <code>Var.Campo</code>, podemos ver isso no código acima), depois temos que abrir o cursor, dar um fetch para colocar na variável e depois do uso fechar o cursor! Ufa! Cansei até de &#8220;falar&#8221; tudo isso!! Sem contar que você ao analisar uma rotina que seja grande (umas 3000 linhas por exemplo) onde suas declarações (inclusive seu cursor) está lá em cima do código e de repente você encontra um <code>Open CursorX;</code>&#8230; Nossa! Lá vamos nós fazer uma viagem até a parte de cima da aplicação, encontrar a declaração deste cursor pra poder entender o que ele faz e etc.</p>
<p>Torna muito trabalhoso para manutenção, na minha opinião!</p>
<p>Uma outra forma de utilizar os cursores é colocando a query na hora em que vamos de fato utilizar os dados que ela retorna, ou seja, no meio da aplicação mesmo. Chamamos isso de <strong>Cursor Implícito</strong>.</p>
<p>Repetindo o caso acima só que desta forma, teríamos a nossa procedure da seguinte forma:</p>
<p><code><br />
create or replace procedure entendendoCursor is<br />
Begin<br />
--Faz o Loop já informando a variável de retorno (rCli neste caso) e o select que será executado<br />
For rCli in (Select codigo,<br />
nome,<br />
cpf<br />
from clientes)<br />
Loop<br />
--Exibe na tela as informações do cliente<br />
dbms_output.put_line('Código: '||rCli.codigo||' Nome: '||rCli.nome||' CPF: '||rCli.cpf);<br />
End loop;<br />
End;<br />
</code></p>
<p>Mais simples não? No primeiro exemplo temos 29 linhas e no segundo nossa procedure cai para 12 linhas. Além de escrever menos, fica bem mais simples de ler em caso de um código grande e além de tudo, não precisamos ficar com a responsabilidade de abrir cursor, ler cursor, coloca na variável, verifica se acabou os dados para sair do laço (%notFound), fecha cursor e etc, o banco faz tudo isso para nós, por isso que chamamos de <strong>Cursor Implícito</strong>, porque todo esse controle é feito pelo banco digamos que &#8220;por baixo dos panos&#8221;!</p>
<p>Bom, esta é minha humilde opinião quanto ao uso de cursores, lembrando que cada um tem sua forma de fazer, creio eu que a forma mais simples sempre é a melhor para fazer e claro, para dar manutenção posteriormente. Lembro ainda que existem outras formas de realizarmos selects nos nossos programas PL/SQL, podemos usar query´s dinâmicas e etc, quem manda é o freguês!!</p>
<p>Lembro ainda que é extremamente interessante comentar nossos códigos, escrever de forma de se algum outro desenvolvedor pegue para dar manutenção consiga entender o que está sendo feito a cara passo do nosso código.</p>
<p>Espero que gostem e comentem!!</p>
<p>Até a próxima!</p>
<p>Atc.<br />
Gerson Júnior</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2009/03/19/cursor-no-oracle-plsql/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
