<?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; functions</title>
	<atom:link href="http://www.diaadiaoracle.com.br/category/functions/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>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>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>Função DECODE no Oracle SQL</title>
		<link>http://www.diaadiaoracle.com.br/2009/07/15/funcao-decode-no-oracle-sql/</link>
		<comments>http://www.diaadiaoracle.com.br/2009/07/15/funcao-decode-no-oracle-sql/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 16:58:00 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[decode]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=12</guid>
		<description><![CDATA[Fala PessoAll,
Hoje vamos falar de Construção de SQL.
As vezes precisamos fazer umas coisas mais avançadas num comando SQL e aí precisamos utilizar alguns recursos mais interessantes que o Oracle nos proporciona.
Quem nunca pensou: &#8220;Ai como seria bom se tivesse um IF no select&#8221;. Tem sim!
O primeiro recurso que podemos utilizar é o DECODE, essa função [...]]]></description>
			<content:encoded><![CDATA[<p>Fala PessoAll,</p>
<p>Hoje vamos falar de <strong>Construção de SQL</strong>.</p>
<p>As vezes precisamos fazer umas coisas mais avançadas num comando SQL e aí precisamos utilizar alguns recursos mais interessantes que o <strong>Oracle</strong> nos proporciona.</p>
<p>Quem nunca pensou: &#8220;Ai como seria bom se tivesse um IF no select&#8221;. Tem sim!</p>
<p>O primeiro recurso que podemos utilizar é o <strong>DECODE</strong>, essa <strong>função</strong> é bem interessante e quebra um bocado de galhos, vamos ver um exemplo pra &#8220;clarear&#8221; as idéias.</p>
<p>Suponha que você tem uma tabela que contém o sexo das pessoas, mas na tabela só armazena F ou M e você quer que seja mostrado &#8220;Masculino&#8221; e &#8220;Feminino&#8221; no retorno do seu <strong>select</strong>, como fazemos isso no select? Com <strong>DECODE</strong>!</p>
<p>Assim:</p>
<p><code><br />
select nome,<br />
dt_nascimento,<br />
decode(sexo,<br />
'M', 'Masculino',<br />
'F', 'Feminino',<br />
'Indefinido') sexo<br />
from pessoas;<br />
</code></p>
<p>Como funciona isso&#8230; o <strong>DECODE</strong> testa o valor que você passa no primeiro parâmetro e vai comparando com o que você especifica e retorna o que você deseja. Complexo não? NÃO!! Vamos explicar o nosso exemplo:</p>
<p>No exemplo acima é passado o campo <code>sexo</code>, em seguida passamos o primeiro valor de teste e o que vai retornar caso encontre este valor, que neste caso é: Se encontrar <code>'M'</code> retorne <code>'Masculino'</code>, sempre aos pares. Ou seja, valor encontrado e logo depois o valor que vai retornar. Como podemos ver, depois vem mais um par&#8230; <code>'F'</code> e <code>'Feminino'</code> o que nos diz que se encontrar um <code>'F'</code>, traga <code>'Feminino'</code> na coluna.</p>
<p>Tá, mas e esse último valor que tem <code>'Indefinido'</code>? Ele não tem par!! Vai dar erro? Não, esse é uma espécie de <strong>ELSE</strong> do <strong>DECODE</strong>&#8230; se ele não encontrar nenhuma das alternativas passadas para retornar um valor especificado, ele retorna esse último valor. No nosso exemplo, podemos ver que caso não encontre <code>'M'</code> nem <code>'F'</code> no campo, ele irá retornar o valor <code>'Indefinido'</code> para a coluna&#8230; agora ficou claro!</p>
<p>O <strong>DECODE</strong> não tem um limite mínimo nem máximo de &#8220;pares de teste e retorno&#8221;, você pode ir especificando os valores e os retornos de acordo com sua necessidade.</p>
<p>Bom, esse é um recurso do <strong>Oracle</strong> que pode ser bem útil para pessoas que fazem <strong>SQL</strong>, que elaboram <strong>relatórios</strong>, que vivem fazendo <strong>query</strong> entre outros casos.</p>
<p>Como podemos verificar, para usar o <strong>DECODE</strong> nós temos que saber os valores que estão na coluna para que possamos informar qual o retorno caso determinado valor seja encontrado, mas&#8230; e se eu quiser utilizar uma faixa de valores por exemplo? Tipo&#8230; se coluna <code>nota</code> estiver entre <code>0</code> e <code>3</code> retorno <code>'Péssimo'</code>, entre <code>4</code> e <code>5</code> retorne <code>'Ruim'</code>, entre <code>6</code> e <code>8</code> retorne <code>'Bom'</code> e acima de <code>8</code> retorne <code>'Ótimo'</code>? Não dá pra fazer isso com <strong>DECODE</strong> né? Mas, tenha calma&#8230; no próximo post falaremos sobre uma outra <strong>função</strong> do <strong>Oracle</strong> que é uma espécie de <strong>DECODE</strong> avançado, que permite esse tipo de teste e muito mais.</p>
<p>Espero que gostem e que seja útil. Até a próxima.</p>
<p>Não exitem em comentar e/ou mandar e-mails.</p>
<p>Atc.<br />
Gerson Júnior<br />
gerson.vasconcelos@gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2009/07/15/funcao-decode-no-oracle-sql/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Oralce PL/SQL &#8211; Funções (Funtions) e Procedures</title>
		<link>http://www.diaadiaoracle.com.br/2009/03/27/oralce-plsql-funcoes-funtions-e-procedures/</link>
		<comments>http://www.diaadiaoracle.com.br/2009/03/27/oralce-plsql-funcoes-funtions-e-procedures/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 20:22:00 +0000</pubDate>
		<dc:creator>oracle</dc:creator>
				<category><![CDATA[functions]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[procedures]]></category>

		<guid isPermaLink="false">http://www.diaadiaoracle.com.br/?p=6</guid>
		<description><![CDATA[Fala PessoAll,
Bom&#8230; hoje em mais um dia a dia de trabalho, rolou mais uma dúvida sobre o uso de procedures e funções no PL/SQL. Aí fiz a seguinte pergunta: Qual a diferença entre Procedure e Function no PL/SQL? Aí surgiram aquelas velhas respostas decoradas da faculdade: &#8220;Procedure não retorna valor!&#8221;, &#8220;Função retorna valor e procedure [...]]]></description>
			<content:encoded><![CDATA[<p>Fala PessoAll,</p>
<p>Bom&#8230; hoje em mais um dia a dia de trabalho, rolou mais uma dúvida sobre o uso de procedures e funções no PL/SQL. Aí fiz a seguinte pergunta: Qual a diferença entre Procedure e Function no PL/SQL? Aí surgiram aquelas velhas respostas decoradas da faculdade: &#8220;Procedure não retorna valor!&#8221;, &#8220;Função retorna valor e procedure não retorna.&#8221;, entre outras. Vamos lá então:</p>
<p>No Oracle a diferença básica entre uma e outra é que a Function OBRIGATÓRIAMENTE tem que retornar um valor, você pode até criar a função e compilar ela sem um Return, mas na hora que você rodar esta função você vai obter um erro oracle dizendo que: &#8220;Function Retorned withou value&#8221;, ou seja, função não retorna nenhum valor (algo parecido), e não funciona. Porque a diferença básica? Porque procedures no Oracle também podem retornar valores, isso mesmo, basta você criar um parametro do tipo OUT, assim:<br />
<code><br />
create or replace procedure pr_teste(p_t number, p_ret out varchar2) is<br />
begin<br />
if(p_t = 1) then<br />
p_ret := 'É 1';<br />
else<br />
p_ret := 'Não é 1';<br />
end if;<br />
end;<br />
</code><br />
Neste exemplo de código, note que estamos atribuindo ao parâmetro <code>p_ret</code> o valor que será retornado para o local que chamou essa procedure (veremos exemplo desta chamada nos exemplos a seguir).</p>
<p>Ah&#8230; então, se as duas retorna valor, porque eu tenho procedure e function? E porque eu uso uma e não outra ou a outra e não uma?</p>
<p>Vamos aos pontos de cada uma delas:</p>
<p><strong>Nas Funtions:</strong><br />
- Pode ser usada em comandos select, insert etc para ser retornada como uma coluna da query:<br />
<code>select codigo, nome, fn_calculaIdade(codigo) Idade from pessoas;</code> Neste exemplo, fn_calculaIdade recebe o codigo da pessoa como parametro e retorna a idade dela, isso será exibido como uma coluna na query com nome <code>Idade</code></p>
<p>- Pode ser atribuida diretamente a uma variável:<br />
<code><br />
declare<br />
v_idade number;<br />
begin<br />
.<br />
.<br />
v_idade := fn_calculaIdade(codigo);<br />
.<br />
.<br />
end;<br />
</code></p>
<p>Neste exemplo, estamos no meio de um bloco PL/SQL e atribuímos diretamente a uma variável o valor que retornará da função.</p>
<p>E mais algumas coisas sobre função.</p>
<p><strong>Nas Procedures:</strong><br />
- O grande &#8220;plus&#8221; das procedures é: Podem retornar mais de um resultado! Ah&#8230; isso mesmo, essa é a grande vantagem das procedures, existe a possibilidade de ser retornado mais de um retorno (retornar retorno, coisa feia não? você entenderá jájá), coisa que é completamente impossível usando função. Funções só retornam um único resultado.</p>
<p>Complicou? Vamos ao exemplo:</p>
<p>Primeiro vamos criar uma procedure com 3 (isso mesmo 3, três, III, rsrs) parâmetros de retorno:</p>
<p><code><br />
create or replace procedure pr_buscaEndereco(p_codigo_pessoa number, p_rua out varchar2, p_bairro out varchar2, p_cidade out varchar2) is<br />
begin<br />
begin<br />
select rua,<br />
estado,<br />
cidade<br />
into p_rua,<br />
p_bairro,<br />
p_cidade<br />
from pessoas<br />
where codigo = p_codigo_pessoa;<br />
exception<br />
when no_data_found then<br />
p_rua    := 'Rua não encontrada.';<br />
p_bairro := 'Bairro não encontrada.';<br />
p_cidade := 'Cidade não encontrada.';<br />
end;<br />
end;<br />
</code><br />
Note que os parâmetros que serão usados para retorno, tem uma cláusula OUT na frente do tipo, isso que diferencia ele de um parâmetro comum, IN.</p>
<p>Ah&#8230; bom, mas e como é que eu vou usar isso? Assim:<br />
<code><br />
declare<br />
v_pessoa_rua    varchar2(100);<br />
v_pessoa_bairro varchar2(100);<br />
v_pessoa_cidade varchar2(100);<br />
begin<br />
pr_teste(212, v_pessoa_rua, v_pessoa_bairro, v_pessoa_cidade);<br />
dbms_output.put_line('Endereço da pessoa 212: Rua: '||v_pessoa_rua||' Bairro: '||v_pessoa_bairro||' Cidade: '||v_pessoa_cidade);<br />
end;<br />
</code></p>
<p>Neste exemplo, temos três variáveis criadas, estas três variáveis são passadas na chamada da procedure e como estes parâmetros no qual elas são passadas são OUT, irão retornar algum valor, que será o valor da variável após execução da procedure.</p>
<p>É isso aí, portanto, caso você precise de uma função que retorne mais de um valor, não tente criar uma função genérica cheia de IF&#8217;s e chamar ela mais de uma vez fazendo o mesmo select em colunas diferentes, use uma procedure com mais de um parâmetro OUT que isso provavelmente resolverá seus problemas.</p>
<p>Momento DBA: Lembrem que quanto menos funções são chamadas, mais agradável para o banco. A cada função que chamamos o banco vai ter que ver, executar, retornar, isso usa memória, processador e etc. Se no lugar de 10 chamadas para uma função voce usar uma procedure com 10 parametros OUT, é bem menos &#8220;doloroso&#8221; para o banco. Outra coisa que é muito importante e que ocorre muito é usar função para retornar como uma determinada coluna de um comando select&#8230; lembre-se que se está função está na clausula <code>select</code> ela será chamada exatamente a quantidade de vezes de quantos registros existirem. No exemplo da função <code>fn_calculaIdade</code> que citei lá em cima, se tivermos 1.000.000 de registros, esta função será executada 1.000.000 de vezes, se é uma função mais robusta e complexa, imagine pra onde vai a performance da sua query. Além da perda de performance na query, de quebra você ainda perde uma credibilidade com o DBA! Que quando você degradar o banco todo, ele vai ficar bravo com você!!</p>
<p>Grande abraço a todos.</p>
<p>Fiquem a vontade para comentários e/ou e-mails.</p>
<p>Atc.<br />
Gerson Júnior<br />
gerson.vasconcelos@gmail.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.diaadiaoracle.com.br/2009/03/27/oralce-plsql-funcoes-funtions-e-procedures/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
