SYSDATE redundante

Este forum é dedicado a códigos errados que se encontram por aí, ou seja, coisas que não se deve fazer de jeito nenhum! Não coloque neste forum dúvidas! (apenas situações bizarras do nosso dia a dia :-)
Responder
NiNo
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 62
Registrado em: Seg, 11 Jul 2005 2:03 pm
Localização: são Paulo
NiNo
Developer

Selecionar tudo

Declare
  vData Date;
Begin
  Select Sysdate Into vData From Dual;
Exception
  When Others Then
    vDate := Sysdate;
End;
mportes
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 13
Registrado em: Ter, 01 Nov 2005 11:53 pm
Localização: São Paulo
Contato:

Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Márcio, bom dia.

Poderia estar postando o código aqui no Fórum???
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

É uma pena, eu também não consegui ver...
Eu adoro o blog do Márcio Portes... Mas pelo fato de ser um BLOG, o site é bloqueado em muitas empresas que eu já trabalhei. (bloqueiam a string BLOG)...
Mas é certo que vou olhar em casa :-D
Avatar do usuário
Toad
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 253
Registrado em: Sex, 18 Nov 2005 2:14 pm
Localização: Seattle, WA
Contato:
Matheus Gonçalves
matheus.dev
twitter.com/developer__c

Um colega teve uma dúvida em uma lista de discussão e me motivou a escrever sobre o assunto aqui, já que acredito que seja de interesse comum. Trata-se do uso indevido e indiscriminado da cláusula WHEN OTHERS nos códigos PL/SQL.

Assim como em qualquer linguagem de programação, no PL/SQL também podemos tratar as exceções. O problema é que, muitas vezes, por "falta de tempo" ou preguiça mesmo, muitos codificadores (DBAs, analistas, etc), simplesmente para que seus códigos não apresentem erro, jogam a cláusula EXCEPTION WHEN OTHERS then NULL para evitar que o programa seja abortado. Isso em 99% dos casos é um BUG. A cláusula mascara qualquer exceção no programa e torna muito difícil a depuração do código.

Vamos a um exemplo hipotético (porque isso nunca acontece na vida real) faltando 5 dias para o fechamento do mês, o gerente resolve atender a uma premiação que a diretoria autorizou e pede aos desenvolvedores que codifiquem uma função para aumentar em 10% o salário dos funcionários. Como o desenvolvedor é um analista sagaz, ele não pode deixar que seu código aborte, então ele vai tratar TODAS as exceções através do WHEN OTHERS. Veja o prejuízo dos funcionários.

Selecionar tudo

ops$marcio@ORA10G> create table func as select empno, ename, sal from scott.emp;

Table created.

ops$marcio@ORA10G>
ops$marcio@ORA10G> create or replace function
  2  aumenta_sal( sal in number ) return number
  3  is
  4     l_novo_sal  number default 0;
  5  begin
  6     l_novo_sal := sal / 0; -- ops! certamente um erro!
  7  end;
  8  /

Function created.

ops$marcio@ORA10G> show error
No errors.
Sem erros! Porém, quando o desenvolvedor que implementou o roda_folha começa a testar seu programa, ele não quer saber de problemas, assim já lança mão da cláusula when others e NULL para realmente não ter surpresas.

Selecionar tudo

ops$marcio@ORA10G>
ops$marcio@ORA10G> create or replace procedure
  2  roda_folha
  3  is
  4  begin
  5    update func
  6       set sal = aumenta_sal(sal);
  7  exception
  8    when others then
  9       null;
 10  end;
 11  /

Procedure created.

ops$marcio@ORA10G> show error
No errors.
E nossos heróis esperançosos com o aumento!

Selecionar tudo

ops$marcio@ORA10G> select * from func;

        EMPNO ENAME                SAL
------------- ---------- -------------
         7369 SMITH                800
         7499 ALLEN               1600
         7521 WARD                1250
         7566 JONES               2975
         7654 MARTIN              1250
         7698 BLAKE               2850
         7782 CLARK               2450
         7788 SCOTT               3000
         7839 KING                5000
         7844 TURNER              1500
         7876 ADAMS               1100
         7900 JAMES                950
         7902 FORD                3000
         7934 MILLER              1300

14 rows selected.

ops$marcio@ORA10G> exec roda_folha

PL/SQL procedure successfully completed.
Nenhum problema quando rodamos a folha. Os operadores felizes, não acionaram ninguém aquela noite!
Mas no outro dia! ;)

Selecionar tudo

ops$marcio@ORA10G>
ops$marcio@ORA10G> select * from func;

        EMPNO ENAME                SAL
------------- ---------- -------------
         7369 SMITH                800
         7499 ALLEN               1600
         7521 WARD                1250
         7566 JONES               2975
         7654 MARTIN              1250
         7698 BLAKE               2850
         7782 CLARK               2450
         7788 SCOTT               3000
         7839 KING                5000
         7844 TURNER              1500
         7876 ADAMS               1100
         7900 JAMES                950
         7902 FORD                3000
         7934 MILLER              1300

14 rows selected.
O que deveria ser:

Selecionar tudo

ops$marcio@ORA10G>
ops$marcio@ORA10G> select func.*, sal * 1.10 novo_sal
  2    from func;

        EMPNO ENAME                SAL      NOVO_SAL
------------- ---------- ------------- -------------
         7369 SMITH                800           880
         7499 ALLEN               1600          1760
         7521 WARD                1250          1375
         7566 JONES               2975        3272,5
         7654 MARTIN              1250          1375
         7698 BLAKE               2850          3135
         7782 CLARK               2450          2695
         7788 SCOTT               3000          3300
         7839 KING                5000          5500
         7844 TURNER              1500          1650
         7876 ADAMS               1100          1210
         7900 JAMES                950          1045
         7902 FORD                3000          3300
         7934 MILLER              1300          1430

14 rows selected.
Este pequeno exemplo tentou ilustrar o que ocorre com a má prática de programação quando se utiliza o artifício da cláusula WHEN OTHERS.

A dúvida do colega é se há alguma maneira de bloquear o uso da cláusula WHEN OTHERS em código fonte de triggers. O recomendável é prevenir em todos os códigos!
Se é para ser drástico, vou matar o mal pela raiz. O método usado foi: criei uma trigger de evento de DDL (create e alter), verifiquei se o CREATE ou ALTER era para trigger e busquei no código fonte o WHEN OTHERS; encontrado, devolvo um erro de usuário com uma mensagem "Uso indesejável do WHEN OTHERS"!
Demonstrando:

Selecionar tudo

ops$marcio@ORA10G> create or replace trigger prevent_when
  2     after create or alter on schema
  3  declare
  4     sql_text ora_name_list_t;
  5     stmt     varchar2(2000);
  6     n        number;
  7  begin
  8     if ( ora_dict_obj_type = 'TRIGGER' ) then
  9        n := ora_sql_txt(sql_text);
 10        for i in 1 .. n
 11        loop
 12            stmt := stmt || sql_text(i);
 13        end loop;
 14        if ( instr(upper(stmt), 'WHEN OTHERS') > 0 ) then
 15           raise_application_error( -20001, 'Uso indesejavel do WHEN OTHERS');
 16        end if;
 17     end if;
 18  end;
 19  /

Trigger created.

ops$marcio@ORA10G>
ops$marcio@ORA10G> create table t ( x int );

Table created.

ops$marcio@ORA10G> create or replace trigger t_bi_fer
  2  before insert on t for each row
  3  declare
  4     n number;
  5  begin
  6     n := 10/0;
  7  exception
  8    when others then
  9       null;
 10  end;
 11  /
create or replace trigger t_bi_fer
                          *
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Uso indesejavel do WHEN OTHERS
ORA-06512: at line 13
Obviamente, o exemplo acima deve ser aperfeiçoado, já que é possível separar WHEN OTHERS em duas linhas ou colocar mais espaços entre eles. A demonstração serve apenas para uma idéia de como implementar o bloqueio.

No texto todo, nota-se claramente o uso excessivo da cláusula WHEN OTHERS. Isso foi proposital, para frisar. Assim, quando a virem em algum código lembrem-se do que foi discutido aqui.

Retirado de : http://mportes.blogspot.com/2005/07/boa ... thers.html

:-o
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 13 visitantes