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 :-)
  

Mensagemem Seg, 23 Out 2006 4:44 pm

Código: Selecionar todos
Declare
  vData Date;
Begin
  Select Sysdate Into vData From Dual;
Exception
  When Others Then
    vDate := Sysdate;
End;
NiNo
Localização: Sao Paulo

NiNo
Developer

Mensagemem Sáb, 28 Abr 2007 7:15 pm

mportes
Localização: São Paulo


Mensagemem Seg, 30 Abr 2007 8:32 am

Márcio, bom dia.

Poderia estar postando o código aqui no Fórum???
Trevisolli
Localização: Araraquara - SP

Abraço,

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

Mensagemem Seg, 30 Abr 2007 9:18 am

É 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
dr_gori
Localização: Portland, OR USA

Thomas F. G

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

Mensagemem Sex, 04 Mai 2007 10:22 am

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.

Código: Selecionar todos
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.

Código: Selecionar todos
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!

Código: Selecionar todos
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! ;)

Código: Selecionar todos
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:

Código: Selecionar todos
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:

Código: Selecionar todos
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
Toad
Localização: Seattle, WA

Matheus H. Gonçalves
www.toad.com.br
www.twitter.com/toadgeek



Voltar para Códigos Duvidosos

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante