Social Icons

Mostrando postagens com marcador PL/SQL. Mostrar todas as postagens
Mostrando postagens com marcador PL/SQL. Mostrar todas as postagens

30 de mai. de 2023

Features do PL/SQL Compiler para otimizar e melhorar a qualidade do seu código


Olá pessoal,

     Para aqueles que não estão acompanhando, informo que estou ministrando 2 aulas mensais gratuitas de PL/SQL preparatórias para o exame 1Z0-149, e vou compartilhar neste post uma dessas aulas, em que falo sobre o uso do PL/SQL compiler, visando obter melhor desempenho ou melhorar a qualidade do seu código:

4 de dez. de 2022

Aulas de PLSQL gratuitas preparatórias para o exame 1Z0-149


 

Olá Pessoal,

     No post de hoje quero compartilhar com vocês uma informação que pode lhe ser útil, caso você queira ou precise estudar/aprender PL/SQL. A cada 14 dias (aproximadamente) estou ministrando aulas de PL/SQL para a DBAOCM, que são totalmente gratuitas durante o horário da Live, e elas ocorrem em datas/horários previamente agendados (ver abaixo), no canal do YouTube da DBAOCM. Após a apresentação a aula sai do ar e fica disponível "em algum lugar" somente para os alunos deles. 

8 de mai. de 2018

Apresentação da palestra "Programando em PL/SQL, dicas de padrões e de tuning para DBAs e Desenvs"




Olá pessoal,

     Conforme prometido na palestra  "Programando em PL/SQL, dicas de padrões e de tuning para DBAs e Desenvolvedores", que fiz em 5/5/18 às 9:30h no "DBA Brasil 3.0", estou compartilhando neste post o arquivo PDF utilizado na apresentação.

3 de mai. de 2017

Performance de objetos PL/SQL compilados para debbuging




 Olá pessoal,

     Todo DBA ou Desenvolvedor que programa em PL/SQL há algum tempo ou participou de algum curso sobre essa linguagem, provavelmente sabe que existem 2 modos de compilação de blocos PL/SQL: nativo e interpretado, e que o modo interpretado pode ser compilado para debug ou não!

21 de fev. de 2017

Escrevendo no alert.log com PL/SQL


 
Olá pessoal,

     No artigo de hoje vou mostrar como escrever no alert.log com apenas uma linha de código, dentro de um bloco PL/SQL. Um procedimento simples e muito útil!

14 de mai. de 2015

Executando comandos do Sistema Operacional em SQL e PL/SQL


ATUALIZADO EM 27/07/2018


Olá pessoal,

     No artigo de hoje vou mostrar como executar comandos do Sistema Operacional dentro de um Banco de Dados Oracle, utilizando o package OS_COMMAND, a partir de instruções SQL ou PL/SQL.

29 de dez. de 2014

Recuperando a versão anterior de objetos PL/SQL (Stored Procedures, Functions etc.)



Olá pessoal,

     No artigo de hoje vou demostrar como recuperar a versão anterior de uma Stored Procedure, Função ou qualquer objeto PL/SQL armazenado em um Banco de Dados Oracle. Antes disso, porém, iremos entender em que situação essa recuperação é útil.

31 de jul. de 2014

Gerando arquivos DSV com PL/SQL


ATUALIZADO EM 17/5/19


Olá pessoal,

      No artigo de hoje vou mostrar como gerar um arquivo texto em formato DSV (Delimited Separated Values) de forma simples e rápida, utilizando apenas uma função que criaremos no Banco de Dados. O arquivo será gerado a partir do resultado de uma instrução SQL e terá o conteúdo das linhas de seu resultado com cada valor de coluna separado por algum caractere definido por você, como por exemplo, o caractere ponto e vírgula (;). Opcionalmente, é possível incluir no arquivo DSV um cabeçalho gerado de forma dinâmica (ver parâmetro "p_inclui_cabecalho" da funçãoo que mostrarei adiante), que contém a descrição das colunas inclusas no SQL. 

9 de jun. de 2014

Dicas para programação em PL/SQL



Olá pessoal,

   No artigo de hoje darei algumas dicas que são muito importantes para quem deseja escrever código PL/SQL com qualidade e de fácil reutilização. Algumas dessas dicas se aplicam em qualquer linguagem de programação (Itens 1, 2, 3 e 7) e são bem simples e fáceis de aplicar, portanto, qualquer iniciante conseguirá utilizá-las. Outras (Itens 4, 5 e 6), para melhor entendimento, exigem experiência ou conhecimentos de nível intermediário/avançado.

9 de jan. de 2013

Enviando e-mails com PL/SQL em Bancos de Dados Oracle - Parte 2


Olá pessoal,

     Dando continuidade ao artigo Enviando e-mails com PL/SQL em Bancos de Dados Oracle, irei compartilhar nesta 2a. parte, uma package chamada PKG_ENVIA_EMAIL, que eu desenvolvi para facilitar o trabalho de envio de e-mails com ou sem anexo. Essa package internamente utiliza a package UTL_MAIL para enviar mensagens sem anexo e a package UTL_SMTP para enviar mensagens com anexo do tipo texto. O objetivo de criá-la foi o de padronizar o código de envio de e-mails na empresa em que eu trabalho e facilitar o envio de e-mails com anexos maiores que 32K, pois não é muito fácil utilizar a package UTL_SMTP para essa finalidade (para mais informações sobre este assunto, leia a 1a. parte do artigo).
   
     O package PKG_ENVIA_EMAIL pode ser baixado a partir de um script protegido com senha (para recebê-la assine a newsletter que encontra-se no painel direito deste blog.) e que está disponível para download em arquivo compactado, no link script_pkg_envia_email.zip. O package pode ser instalada e utilizada em qualquer schema de usuário de um SGBD Oracle, desde que sejam atendidos os pré-requisitos especificados na 1a. parte deste artigo.

     O package PKG_ENVIA_EMAIL contém 1 função e 2 stored procedures:

           - FC_GERAR_ARRAY_STRING:
               Função privada que permite gerar array para separar destinatários e enviar o e-mail para múltiplos destinatários.quando necessário.

           - SP_ENVIAR_EMAIL:
               Stored Procedure pública que pode ser utilizada para enviar e-mails sem anexo. Utiliza internamente a package UTL_MAIL.

           - SP_ENVIAR_EMAIL_COM_ANEXO:
               Stored Procedure pública que pode ser utilizada para enviar e-mails COM anexo do tipo texto. Utiliza internamente a package UTL_SMTP e permite enviar somente 1 anexo por e-mail.
           
     Se você precisar mandar outros tipos de anexos, tais como arquivos de vídeo ou som, e/ou precisar mandar mais de 1 arquivo texto anexo, crie nova(s) procedure(s) com sobrecarga dentro da package PKG_ENVIA_EMAIL, incluindo o código necessário para executar essas tarefas. Para isso, você precisará estudar, em detalhes, como utilizar a package UTL_SMTP.

     Para enviar um e-mail sem anexo, execute a stored procedure SP_ENVIAR_EMAIL, como no exemplo abaixo:

   BEGIN
    PKG_ENVIA_EMAIL.SP_ENVIAR_EMAIL (P_ASSUNTO => 'Assunto do e-mail', 
       P_MSG => 'Mensagem', 
       P_EMAIL_ORIGEM => 'oracle@oracle.com', 
       P_EMAIL_DESTINO => 'fbifabio@gmail.com, jack@oracle.com',
       P_EMAIL_CC_DESTINO => 'ze@oracle.com, jo@oracle.com',
       P_EMAIL_CCO_DESTINO => null);
   END;

     Para enviar um e-mail com anexo do tipo texto, execute a stored procedure SP_ENVIAR_EMAIL_COM_ANEXO, como no exemplo abaixo:

   DECLARE
     v_CLOB CLOB;
   BEGIN
    PKG_ENVIA_EMAIL.SP_ENVIAR_EMAIL_COM_ANEXO (P_ASSUNTO => 'Assunto do e-mail',
       P_MSG => 'Mensagem', 
       P_EMAIL_ORIGEM => 'oracle@oracle.com', 
       P_EMAIL_DESTINO => 'fbifabio@gmail.com, jack@oracle.com',     
       P_EMAIL_CC_DESTINO => 'ze@oracle.com, jo@oracle.com', 
       P_EMAIL_CCO_DESTINO => null,
       P_FILENAME => 'arquivo.txt',
       P_ANEXO => v_CLOB,  -- variável CLOB c/ texto do arquivo
       P_ATTACH_MIME => 'text/plain; charset=iso-8859-1', 
       P_SMTP_SERVER => 'smtp.empresa.com.br',
       P_SMTP_PORT => 25);
   END;



Bom pessoal, por hoje é só!


[]s
     

2 de jan. de 2013

Enviando e-mails com PL/SQL em Bancos de Dados Oracle


Olá pessoal,

     O assunto de hoje é a 1ª parte de um artigo (dividido em 2 partes) em que vou compartilhar conhecimentos gerais sobre como enviar e-mails a partir de um SGBD Oracle e mostrarei como evitar os principais problemas que você poderá encontrar tentando realizar esta tarefa. Alguns que eu mesmo passei, outros que alguns leitores do meu blog passaram e me pediram ajuda e outros que vi em fóruns.

 

  Para enviar e-mails a partir de um SGBD Oracle, comumente utilizamos as packages UTL_MAIL e UTL_SMTP, mas é possível utilizar também a package UTL_TCP. Todas elas foram desenvolvidas pela própria Oracle e algumas precisam de instalação adicional. A UTL_SMTP é mais antiga, existe desde o Oracle 8i e já vem instalada, por padrão no BD. A UTL_MAIL está disponível a partir do Oracle 10GR2,  e nada mais é do que um wrapper que utiliza as packages UTL_SMTP e UTL_TCP. Ela foi criada para facilitar o envio de e-mails, mas infelizmente, ela possui algumas restrições.

     Utilizar a package UTL_SMTP para mandar e-mail é bastante complexo e trabalhoso. É bem mais fácil e mais rápido utilizar a package UTL_MAIL, mas como eu havia dito no parágrafo acima, ela possui algumas restrições, tais como: enviar somente 1 anexo e o tamanho do anexo deve ser de no máximo 32K. Estas restrições não existem na package UTL_SMTP, que não vou explicar neste artigo. Na 2a. parte vou compartilhar uma package que usa tanto a UTL_SMTP quanto a UTL_MAIL para enviar e-mails. O código desta package poderá servir como referência para quem pretende ver como usar qualquer uma delas.

     Explicarei abaixo como usar a UTL_MAIL, por ser a opção mais simples e atualmente a mais utilizada. Para utilizá-la é necessário cumprir alguns pré-requisitos:

          1- Instalar a package executando os scripts: $ORACLE_HOME/rdbms/admin/utlmail.sql e $ORACLE_HOME/rdbms/admin/prvtmail.plb. A instalação deve ser efetuada por um usuário que tenha privilégios de DBA;
  
          2-  Configurar o parâmetro de sistema SMTP_OUT_SERVER, com um valor contendo o nome ou IP + porta de um servidor SMTP válido. Se você omitir o endereço da porta, será utilizada como padrão, a porta 25. É importante salientar que a máquina host do BD tenha comunicação com o servidor SMTP, e  também, autorização para enviar mensagens (no software do servidor SMTP não deve existir regras que bloqueiem mensagens da máquina host do BD).
              Ex.: ALTER SYSTEM SET smtp_out_server = 'smtp.empresa.com.br:25';

        Obs.: Para executar o comando acima é necessário ter privilégios de DBA.

          3- O remetente (sender) do e-mail deve ser uma conta de e-mail que não requer autenticação para envio de mensagens.

     Após cumprir os pré-requisitos acima, você já poderá utilizar a package UTL_MAIL. Segue abaixo, um bloco PL/SQL simples, que contém comentários sobre o que deve ser passado como valor em cada parâmetro, e que pode ser utilizado para enviar um e-mail sem anexo, utilizando a procedure SEND desta package:

     BEGIN
          UTL_MAIL.SEND
               (SENDER => 'email@oracle.com', -- remetente da mensagem
                  RECIPIENTS => 'fbifabio@gmail.com',  -- destinatário da mensagem
                  CC => null -- destinatário copiado na mensagem
                  BCC => null -- destinatário com cópia oculta da  mensagem
                  SUBJECT =>  'Assunto do e-mail'-- assunto da mensagem
                  MESSAGE => 'Mensagem do e-mail'-- mensagem do e-mail
                  MIME_TYPE => 'text/plain; charset=iso-8859-1-- mime type + character set do texto da mensagem
               );
     END;

     Como pode ser observado no bloco PL/SQL acima, é muito fácil enviar uma mensagem sem anexo usando a package UTL_MAIL, mas a coisa complica quando você tem que mandar mensagens com anexo, e fica impossível quando o anexo é maior que 32K. Um detalhe em que muitos profissionais encontram problemas e dificuldades, é a configuração dos caracteres do texto das mensagens e do texto dos anexos, que podem apresentar, em muitos casos, os chamados "caracteres desconfigurados". Para evitar estes caracteres desconfigurados é necessário passar o valor adequado para os parâmetros MIME_TYPE, que indicam o tipo de aplicação e o conjunto de caracteres que será utilizado para compor o texto da mensagem ou do anexo Eu normalmente configuro o valor  'text/plain; charset=iso-8859-1e isso já é suficiente para resolver os meus problemas. Se para você esta configuração apresentar caracteres desconfigurados, troque o valor iso-8859-1 por utf-8 ou us-ascii (valor padrão). Para aqueles que ainda assim tiverem problemas e precisarem de mais informações sobre mime types, sugiro a leitura do artigo http://en.wikipedia.org/wiki/MIME.

     Se você tentar mandar um e-mail em um BD 11G, possivelmente você irá se deparar com erro ORA-24247: acesso à rede negado pela ACL (access control list), pois nesta versão do Oracle, para aumentar a segurança do BD, foi acrescentado um controle de acesso mais rígido às packages UTL_MAIL, UTL_SMTP e outras, em que é necessário conceder privilégios especiais ao usuários que irão executá-las. Não iremos entrar em detalhes sobre ACL neste artigo, mas para conceder estes privilégios a um usuário chamado FABIO, por exemplo, execute os blocos PL/SQL abaixo:

begin
   dbms_network_acl_admin.create_acl (
        acl => '
grant_acl.xml',
        description => '
Permite enviar e-mail e usar outras packages',
        principal => '
FABIO', -- observe que o nome do usuário deve estar sempre em UPPERCASE 
        is_grant => TRUE,
        privilege => 'connect
-- este privilégio concedido é que permite que o usuário envie email através do servidor que será especificado no próximo bloco que chama a SP "assign_acl"
        );
  commit;
end; /


begin 
   dbms_network_acl_admin.assign_acl( 
        acl => 'grant_acl.xml',
        host => 'hostname' -- preencha aqui o nome do host do servidor SMTP
        );
   commit;
end; 

 /

     Na próxima parte deste artigo, compartilharei com vocês, uma package que eu desenvolvi para facilitar o trabalho de envio de e-mails com ou sem anexo. Essa package internamente utiliza a package UTL_MAIL para enviar mensagens sem anexo e a package UTL_SMTP para enviar mensagens com anexo. O objetivo de criá-la foi para padronizar o código de envio de e-mails na empresa em que eu trabalho e facilitar o envio de e-mails com anexos maiores que 32K, pois não é muito fácil utilizar a package UTL_SMTP  para essa finalidade.

   
Por hoje é só! Aguardem a 2a. parte!


A 2a. parte deste artigo já foi publicada AQUI


[]s
   

23 de out. de 2012

Tipos de triggers no Oracle Database



Olá pessoal,

     No artigo de hoje vou apresentar e comentar a resposta da enquete que fiz em meu blog com a pergunta QUANTOS TIPOS DE TRIGGERS EXISTEM NO BD? (ver Figura 1) e que encerrou no dia 17/10/2012. Essa enquete tinha como objetivo gerar polêmica e dúvidas. A pergunta parece simples, mas poucas pessoas acertaram a resposta (4/28) e eu acredito que foi justamente pelo modo que ela foi feita (mesmo modo que é feito na prova de certificação 1Z0-144). Escolhi a questão sobre tipos de triggers, porque recentemente fiz o exame 1Z0-144 Oracle Database 11g: Program with PL/SQL (onde fui aprovado e me tornei PL/SQL Developer OCA) e tive que responder uma questão em que a pergunta tinha um enunciado semelhante. Para ajudar aqueles que prentendem se preparar para este exame, veremos adiante a resposta.

Figura 1 - Enquete "Quantos tipos de triggers existem no BD?"

     Quando nos deparamos com a pergunta quantos tipos de triggers existem no Oracle Database, a pergunta se refere a quantos tipos de triggers existem baseando-se no nível em que elas são disparadas. No Oracle Database, as triggers podem ser disparadas no nível de linha (Row level trigger) ou nível de instrução (Statement level trigger).

     O código de uma trigger em nível de linha é executado uma vez para cada linha da tabela em que está sendo realizada uma instrução SQL de INSERT, UPDATE ou DELETE, ou seja, se você executar uma instrução UPDATE que altera 10 linhas e que tem uma trigger associada, o código desta trigger será executado 10 vezes. Já  na trigger em nível de instrução, o seu código é executado apenas uma vez para qualquer instrução SQL, portanto, o código deste tipo de trigger seria executado apenas 1 vez para aquela instrução UPDATE que altera as 10 linhas! 

     Exemplo de trigger de linha:
           create or replace TRIGGER HR.TR_EMPLOYEES_JH 
               AFTER UPDATE OF JOB_ID ON HR.EMPLOYEES 
           REFERENCING OLD AS LA NEW AS LN
             FOR EACH ROW
           BEGIN
             -- insere historico de cargos anteriores do empregado
             INSERT INTO HR.JOB_HISTORY 
               (EMPLOYEE_ID, START_DATE, END_DATE, JOB_ID, DEPARTMENT_ID) 
             VALUES
               (:LA.EMPLOYEE_ID, :LA.HIRE_DATE, SYSDATE, :LA.JOB_ID, :LA.DEPARTMENT_ID);
           END;


     Exemplo de trigger de instrução:
           create or replace TRIGGER HR.TR_EMPLOYEES_LOG
               BEFORE DELETE ON HR.EMPLOYEES 
           REFERENCING OLD AS LA NEW AS LN  
           BEGIN    
             -- insere historico de cargos anteriores do empregado
             INSERT INTO HR.LOG_EMPREGADOS 
               (ID, DT_INCLUSAO, NM_USER, TP_OPERACAO) 
             VALUES
               (0, SYSDATE, USER, 'ALL');  
           EXCEPTION
             WHEN OTHERS THEN
               NULL;
           END;


     Para aprender mais sobre triggers, consulte os treinamentos abaixo:
          - Presencial: PL/SQL Essentials and Tuning;
          - Videoaulas: PL/SQL Essentials (ao ser adquirido na opção com suporte, você ganhará o módulo PL/SQL Tuning).

[]s
   

10 de ago. de 2012

Artigo SQL Magazine 102: Stored Procedures, Functions e Packages em bancos de dados Oracle



Olá pessoal,

     Já está nas bancas a revista SQL Magazine nº 102, com um artigo meu sobre como Otimizar aplicações com o uso de Stored Procedures, Functions e Packages em bancos de dados Oracle.



     Segue abaixo um resumo deste artigo e a seguir um link para consultar um trecho dele: http://www.devmedia.com.br/stored-procedures-functions-e-packages-em-bancos-de-dados-oracle-revista-sql-magazine-102/25390

Apresentaremos neste artigo o uso de functions, packages e stored procedures como alternativa para otimizar a performance de aplicações que acessam bancos de dados Oracle. Para provar o conceito de que estes objetos podem otimizar a performance das aplicações, demonstraremos em detalhes uma aplicação que acessa e atualiza o banco de dados, simulando simples transferências bancárias, por meio de dois métodos: utilizando somente instruções SQL e utilizando somente stored procedures (dentro de uma package e que utiliza uma function dentro da mesma package). Para finalizar, apresentaremos um benchmark entre os dois métodos para que possamos constatar qual deles tem o tempo de execução menor e, consequentemente, a melhor performance.


Para ler todo o artigo, é necessário comprar a revista ou acessar o site da DEVMEDIA (conteúdo online completo somente para assinantes).

30 de nov. de 2011

Consumindo classes JAVA dentro de um Banco de Dados Oracle


 
Olá pessoal,
    
     No artigo de hoje apresentarei um recurso muito interessante e pouco conhecido no Oracle Database, que permite consumir classes desenvolvidas em JAVA dentro de um Banco de Dados (BD) Oracle, para processar ou interagir com dados dentro do próprio BD.  

11 de out. de 2011

PL/SQL: o que é e quando usar?


Olá pessoal,
    
     No artigo de hoje vou falar um pouco sobre PL/SQL, a linguagem procedural do Oracle Database.
    
     Todos os SGBDs (Sistemas Gerenciadores de Banco de Dados) que eu conheço possuem uma linguagem de programação própria, que estende comandos e instruções não contempladas em SQL. Como exemplos podemos citar o Oracle Database, que possui a linguagem PL/SQL, o SQL Server que possui a linguagem Transaction SQL e o DB2 que possui a linguagem SQL PL. Essas linguagens foram criadas para atender a necessidade de se criar programas dentro do próprio banco de dados e são extremamente úteis para executar tarefas de manutenção do banco de dados e para otimizar transações das aplicações que acessam o banco de dados. No meu blog você encontrará vários artigos que usam código PL/SQL dentro destes cenários de manutenção e otimização, como por exemplo:
    - Otimizando a performance de aplicações com stored procedures;
    - PL/SQL mais rápido: Quando usar CURSORES ou collections (BULK COLLECT em NESTED TABLES)?        
    - Recompilando objetos inválidos no Oracle Database.
       
    Uma das principais vantagens da linguagem PL/SQL é permitir que você escreva programas que ficam armazenados no banco de dados e que podem ser reutilizados por qualquer aplicação/usuário que acesse o banco de dados. Segundo Thomas Kyte, um dos maiores especialistas em Oracle do mundo, PL/SQL é a forma mais rápida de processar dados em Bancos de Dados Oracle. Entenda "processar dados" como não apenas submeter instruções SQL (UPDATE, SELECT, INSERT e DELETE) para o Banco de Dados, mas sim, efetuar transações que consistem de várias estruturas de decisão, loops e processamentos mais complexos. Um bom exemplo disso você poderá ver no meu artigo Otimizando a performance de aplicações com stored procedures.

  
     Como qualquer linguagem de programação, em PL/SQL também é possível escrever código bom ou ruim. Para não escrever código ruim, é necessário entender bem a estrutura do código PL/SQL, os detalhes de sua implementação e até mesmo como ele interage com código SQL.  Para aqueles que tiverem interesse em conhecer melhor esta linguagem, escrever código bem estruturado e com boa performance, recomendo pesquisar o site do Steven Feuerstein (http://www.stevenfeuerstein.com), que é autor de vários livros sobre PL/SQL e que tem um conteúdo muito bom para quem quer aprender e se aperfeiçoar, ou recomendo o treinamento de PL/SQL FABIOPRADO.NET, que é baseado em documentação oficial da Oracle e que contempla além do aprendizado da linguagem, muitas dicas e técnicas (inclusive tuning) ensinadas por Steve Feuerstein, Tom Kyte e outras que aprendi ao longo da minha carreira.
   
    Bom pessoal, por hoje é só! 


[]s

17 de set. de 2011

Otimizando a performance de aplicações com o uso de stored procedures


Olá pessoal,
    
     No artigo de hoje vou comentar sobre o ganho de performance com o uso de stored procedures (SPs), nas aplicações que acessam e/ou atualizam dados em Sistema Gerenciadores de Bancos de Dados Relacionais. As stored procedures, bem como, as functions, packages e triggers, foram implementadas na versão 7 do Oracle Database (1992) e seu uso (em substituição ao uso de instruções SQL submetidas individualmente) pode otimizar drásticamente a performance das aplicações que utilizam SGBDs relacionais, principais aquelas que executam grandes transações.
    
     Apresentarei neste artigo, uma aplicação bem simples que chama uma stored procedure (SP), que   por sua vez, realiza uma transação de transferência bancária entre 2 contas correntes e que contém uma regra de negócio, também simples, para verificar se existe saldo na conta de origem. Sei que muitos profissionais de TI são contra codificar regras de negócios dentro de SPs, pois aprendemos em Engenharia de Software moderna, que as regras de negócio devem ficar na aplicação, em um componente separado, que por sua vez, deve ser armazenado em um servidor de aplicação (e nunca no BD), mas tenho certeza de que você vai gostar do resultado do final deste artigo, se sua prioridade for performance!

     Já desenvolvi várias aplicações com regras de negócio tanto no servidor de aplicação quanto em stored procedures, por isso, posso afirmar que sempre consegui melhor performance naquelas aplicações que chamavam stored procedures. Porém, é importante avaliar e testar cada caso. Para quem nunca codificou regras de negócio em stored procedures, isso pode parecer estranho ou errado, mas a vantagem do ganho de performance, justifica (e muito) a prática. Grandes transações que envolvem manipulação condicional de dados podem ficar mais rápidas com SPs. Entre diversos benefícios de segurança e performance que as stored procedures proporcionam, o principal e que eu acho mais fácil de explicar, é que elas reduzem o tráfego de dados pela rede e o tempo de espera destes dados pela aplicação.

     É muito simples o raciocínio: se uma transação realiza 10 operações no Banco de Dados, o que é mais rápido: sair do servidor de aplicação e ir ao BD 10X (trafegando 10X pela rede), ou ir uma 1X só, executar as 10 operações e retornar o resultado para o servidor de aplicação? Quando você tem que comprar 10 produtos no mercadinho da esquina, o que é mais rápido? Ir 10X trazendo cada vez 1 único produto ou levar uma sacola e trazer os 10 produtos de uma só vez?

     Em aplicações críticas, que exigem alta performance, o que é mais importante: seguir a regra de criar aplicações N camadas (com regras de negócios SEMPRE em um servidor de aplicação) ou usar recursos alternativos (neste caso, as stored procedures) para desenvolver uma aplicação mais rápida
    
    Vou demonstrar a seguir, um exemplo de uma aplicação que eu desenvolvi com o Dot Net Framework 3.5, para provar o conceito de que SPs podem otimizar a performance das aplicações. A aplicação, chamada Teste de performance de transações (ver Figura 1), poderá ser baixada para testes e é totalmente parametrizável (ver arquivo TesteTransacao.exe.config). Ela simula a realização de simples transferências entre contas bancárias, retirando o valor de uma conta corrente (conta origem) e depositando o respectivo valor em outra conta corrente (conta destino).
  

Figura 1 - Tela principal da aplicação "Testes de performance de Transações"
    
     A operação de transferência ocorre em modo transacional (deve fazer tudo ou nada, se 1 passo falhar, desfaz os passos anteriores) e é composta por 3 passos sequenciais:
          1) Verificar se a conta origem possui saldo para efetuar a transferência;
          2) Retirar (sacar) valor da conta origem;
          3) Depositar valor na conta destino;
        
             Obs.: Os passos 2 e 3 são executados somente se a conta origem possuir saldo (verificado no passo 1).

     A aplicação está disponível para download no MEU ONE DRIVE (ver final do painel direito das páginas do meu blog), pasta Oracle -> Scripts, arquivo TesteTransacao.zip. Para efetuar a instalação e utilizá-la, siga os passos abaixo:

        1- Descompacte o arquivo TesteTransacao.zip informando uma senha que deverá ser obtida assinando a newsletter que encontra-se no painel direito deste blog.

        2- Conecte-se no BD desejado e instale os objetos de BD (tabela CONTA e package PKG_CONTA) que estão no arquivo Script_BD_Teste_Transacao.sql. Instale os objetos no schema de um usuário que será utilizado pela aplicação para conectar-se no BD.

        3- Configure os valores (values) dos parâmetros (keys) do arquivo TesteTransacao.exe.config, conforme indicações abaixo:
             a) instance_name = Nome da instância do BD onde os objetos foram criados. Especificar nome de uma instância cadastrada no arquivo tnsnames.ora da máquina em que a aplicação irá ser executada;
             b) user_name = Nome do usuário que a aplicação utilizará para conectar-se no BD;
             c) pwd_user = Senha do usuário que a aplicação utilizará para conectar-se no BD;
             d) idContaOrigem = Número da conta origem;
             e) idContaDestino = Número da conta destino;
             f) vlInicialContaOrigem = Valor inicial da conta origem;
             g) vlInicialContaDestino = Valor inicial da conta destino;
             h) intTotalInteracoes = Valor indicando qtde. de operações de transferências que serão realizadas;
             i) vlTransferencia = Valor da transferência.

     Observações: São pré-requisitos para executar esta aplicação, ter o Dot Net Framework 3.5 instalado (SOs Windows mais recentes já possuem) e o Oracle Data Provider for .Net.
  
    Para efetuar os testes de performance, basta clicar nos 2 botões existentes na tela principal da aplicação: Transferência SQL e Transferência com SP. O botão Transferência SQL submete instruções SQL para o BD, enquanto que, o botão Transferência com SP, executa uma stored procedure no BD (executando dentro de uma procedure os 3 passos em uma única chamada ao BD).
 
     Vejam abaixo, a performance de testes que eu fiz:
  
TESTE executando 1000 transferências bancárias

    a) Tempo de Transferência do botão Transferência SQL (ver Figura 2): 3,8s

Figura 2 - Teste de 1000 transferências com SQL (ad hoc)
     b) Tempo de Transferência do botão Transferência com SP (ver Figura 3)1,7s

Figura 3 - Teste de 1000 transferências com SP



Observações:
    Também disponibilizei o código-fonte da aplicação deste artigo (arquivo Fontes_TesteTransacao.zip), na mesma pasta que disponibilizei a aplicação. A senha para descompactação deste arquivo é a mesma do arquivo da aplicação.

CONCLUSÃO:

     Nos testes realizando 1000 transações conseguimos verificar que a performance delas utilizando SP foi bem superior, apresentando um desempenho 220% mais rápido. A transação bancária deste artigo é bem simples e possui apenas 3 operações. É importante ressaltar que em transações maiores, o ganho de desempenho também será maior!

     Mais detalhes, sobre a estrutura da aplicação, o porquê da stored procedure apresentar um desempenho superior neste exemplo e sobre a implementação de regras de negócio na aplicação ou na stored procedure, eu deixo para explicar nos seguintes treinamentos:
          - SQL Tuning (presencial);
          - PL/SQL Essentials and Tuning (presencial);
          - PL/SQL Tuning (videoaulas).

  Para aqueles que quiserem verificar a opinião de mais profissionais sobre o desempenho das stored procedures e a questão polêmica das regras de negócios dentro delas, sugiro a leitura da discussão Regras de Negócio em Stored Procedures ou Desenvolvimento em Camadas, no Linkedin, Grupo NET Framework - Brasil.


Bom pessoal, por hoje é só!
Espero que tenham gostado. Qualquer dúvida, é só deixar um comentário.

[]s

26 de mai. de 2011

Recompilando objetos inválidos no Oracle Database


Olá Pessoal,

     No artigo de hoje irei comentar sobre uma característica muito interessante do Oracle Database 10G, a recompilação automática de objetos inválidos. Irei dividir este assunto em três partes: dependências locais, depedências remotas e recompilando os objetos inválidos.  

6 de mai. de 2011

PL/SQL mais rápido: Quando usar Cursores ou Collections?


Olá pessoal,
  
     No artigo de hoje iremos aprender um pouco de PL/SQL, a linguagem procedural da Oracle que estende comandos da linguagem SQL. Para entender melhor o que é PL/SQL, sugiro a leitura do artigo PL/SQL: o que é e quando usar?.
   

23 de dez. de 2010

Otimizando ETL com Pipelined Table Functions


  
Olá pessoal,
   
    Neste artigo apresentarei um recurso muito bom para otimizar ETL (Extract, Transform, and Load), que existe no Oracle Database desde a versão 9i, e que chama-se Pipelined Table Function (PTF).

9 de nov. de 2010

Funções recursivas no Oracle Database


Pessoal,
   
     Este artigo é simples e curto e tem como objetivo apenas demonstrar o conceito de recursividade e como utilizar uma função recursiva em um Banco de Dados Oracle.


     Em Ciências da Computação, o termo recursividade é utilizado para a definição de uma subrotina (função ou método) que pode invocar a si mesma. Este conceito é simples na teoria, mas na prática (até o primeiro contato) é um pouco mais complexo. Com o objetivo de facilitar o entendimento de recursividade, iremos criar e utilizar uma função recursiva em um Banco de Dados Oracle.
   
     O código abaixo cria uma função recursiva com o nome fc_recursiva_exemplo, que retorna uma string contendo todos os números entre um valor de início (intContInicio) e um valor fim (intContFim), recebidos como  parâmetros de entrada pela função. Esta função é executada internamente, N vezes (conforme valores de início e fim) e utiliza o parâmetro strVazia, que é preenchido cumulativamente e que deve ser chamado com um valor vazio para 'montar' a string de retorno.
   
CREATE or replace FUNCTION fc_recursiva_exemplo(intContInicio IN NUMBER, intContFim IN NUMBER, strVazia IN VARCHAR2)
RETURN VARCHAR2
is
    intContInicioTemp NUMBER;
    strTemp VARCHAR2(4000);
BEGIN   
    intContInicioTemp:= (intContInicio+1);    

    --dbms_output.put_line('linha: ' || i);
    strTemp:=strVazia || intContInicio || ', ';



    if (intContInicioTemp <= intContFim) then       
        select  fc_recursiva_exemplo(intContInicioTemp, intContFim, strTemp) into strTemp from dual;
    else
        strTemp:=SUBSTR(strTemp,1,LENGTH(strTemp)-2);
    end if;
   
    Return strTemp;
END;

   
   Obs.: Reparem que no código acima, dentro do bloco IF, há uma chamada para a própria função (fc_recursiva_exemplo) que é executada N vezes, até que o valor fim seja alcançado. Isso é feito sem executar uma rotina de loop, utilizando apenas o conceito de recursividade.


     Segue abaixo um exemplo para testar a função:
         select fc_recursiva_exemplo(1,10,'') from dual;
  
    que deverá retornar a seguinte string:
          1, 2, 3, 4, 5, 6, 7, 8, 9, 10
        



 

LINKS ÚTEIS

Total de visualizações de página

Seguidores

Meu One Drive (antigo Sky Drive)