Preciso tratar erro e DATE .

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
franklin_kunioshi
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qui, 03 Jan 2008 9:24 am
Localização: São Paulo

Ola pessoal ...obrigado pela atenção


Estou precisando tratar um erro de DATE ...
Exemplo:

Estou criando um PL/SQL que recebe varios campos, dados de outra tabela,
ele também recebe datas.
só que não pode aceitar datas erradas EXEMPLO

31 de fevereiro..

como faço pra ele fazer uma critica utilizando um if
na PROCEDURE

???

Obrigado
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

Brother,

Não sei se é a melhor saída, mas, fiz um teste aqui, tentando converter uma string em data.
Caso dê erro, é porque veio em formato inválido.

Dá uma olhada e vê se consegue adaptar para o teu caso:

Selecionar tudo

DECLARE 
  v_data DATE;
  
BEGIN 

			SELECT TO_DATE ('19 de Janeiro de 2007')
			  INTO v_data
			  FROM DUAL;
			  
EXCEPTION 			  
WHEN OTHERS THEN  
  IF SQLCODE = -1858
  THEN 
     dbms_output.put_line('Erro ao converter a data. Data em formato inválido. ' || SQLCODE );
  ELSE 
		   dbms_output.put_line('Erro importando dados: ' || SQLERRM);   
  END IF;   

END;
Tineks
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 365
Registrado em: Ter, 24 Mai 2005 2:24 pm
Localização: Araraquara - SP
Cristiano (Tineks)
Araraquara - SP

E ai Franklin, beleza?

você pode tratar pelo código do erro, segue ai um exemplo.

Selecionar tudo

SQL> DECLARE
  2     v_data   DATE;
  3  BEGIN
  4     v_data := TO_DATE ('31/02/2007', 'dd/mm/yyyy');
  5  EXCEPTION
  6     WHEN OTHERS THEN
  7        IF SQLCODE = -1839 THEN
  8           DBMS_OUTPUT.put_line ('Data inválida ');
  9        ELSE
 10           DBMS_OUTPUT.put_line ('erro: ' || SQLCODE || '-' || SQLERRM);
 11        END IF;
 12  END;
 13  /
Data inválida

PL/SQL procedure successfully completed.
[]'s
Tineks
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 365
Registrado em: Ter, 24 Mai 2005 2:24 pm
Localização: Araraquara - SP
Cristiano (Tineks)
Araraquara - SP

Brow, foi mal, não vi que você já tinha respondido..
hehehehe :lol:

[]'s
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

Hehhe, acho q postamos na mesma hora...
Servindo pro brother ai, beleza...

[]s
Tineks
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 365
Registrado em: Ter, 24 Mai 2005 2:24 pm
Localização: Araraquara - SP
Cristiano (Tineks)
Araraquara - SP

Apesar brow,
q são dois SQLCODE diferentes, dessa forma ele pode tratar melhor o erro.

[]'s
franklin_kunioshi
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qui, 03 Jan 2008 9:24 am
Localização: São Paulo

vlw pela ajuda mais é que não é ultilizando DBMS
e sim utilizando Variaveis para armazenar a data
e depois verificar se ela é 31 de fevereiro se for converter para 28 de fevereiro

abaixo to postando o codigo :

Selecionar tudo

CREATE OR replace PROCEDURE proc_cat3 ( p_nr_cat_data_table  IN        VARCHAR2
                                      , p_cd_sistema             OUT   VARCHAR2
                                      , p_cd_processo            OUT   VARCHAR2
                                      , p_cd_retorno             OUT   NUMBER
                                      , p_ds_mensagem            OUT   VARCHAR2
                                      ) IS
                                      
   d_dia  VARCHAR2(2);
   d_mês  VARCHAR2(2);
   d_ano  VARCHAR2(2); 
   dt_fim date;
   
   n_cod_cat NUMBER(15) := 0;
   n_cont    NUMBER(15) := 0;
   CURSOR c_dm IS (SELECT substr(ds_str_data_table, 1,1)  rec_type
                        , substr(ds_str_data_table, 2,1)  action
                        , substr(ds_str_data_table, 3,3)  cat_no
                        , substr(ds_str_data_table, 6,8)  tbl_no
                        , substr(ds_str_data_table, 14,1) tipe
                        , to_char(decode(substr(ds_str_data_table, 19,2),'  ','01',substr(ds_str_data_table, 19,2))) ||'/' ||
                          to_char(substr(ds_str_data_table, 17,2)) ||'/'||
                          to_char( decode( substr(ds_str_data_table, 15,2), '  ','1904'
                                                                          , '90', 19||substr(ds_str_data_table,15,2)
                                                                          , '91', 19||substr(ds_str_data_table,15,2)
                                                                          , '92', 19||substr(ds_str_data_table,15,2)
                                                                          , '93', 19||substr(ds_str_data_table,15,2)
                                                                          , '94', 19||substr(ds_str_data_table,15,2)
                                                                          , '95', 19||substr(ds_str_data_table,15,2)
                                                                          , '96', 19||substr(ds_str_data_table,15,2)
                                                                          , '97', 19||substr(ds_str_data_table,15,2)
                                                                          , '98', 19||substr(ds_str_data_table,15,2)
                                                                          , '99', 19||substr(ds_str_data_table,15,2)
                                                                          ,       20||substr(ds_str_data_table,15,2))) dt_ini
                        , to_char(decode(substr(ds_str_data_table, 25,2),'  ','31',substr(ds_str_data_table,25,2))) ||'/' ||
                          to_char(substr(ds_str_data_table, 23,2)) ||'/'||
                          to_char( decode( substr(ds_str_data_table, 21,2), '  ','1904'
                                                                          , '90', 19||substr(ds_str_data_table,21,2)
                                                                          , '91', 19||substr(ds_str_data_table,21,2)
                                                                          , '92', 19||substr(ds_str_data_table,21,2)
                                                                          , '93', 19||substr(ds_str_data_table,21,2)
                                                                          , '94', 19||substr(ds_str_data_table,21,2)
                                                                          , '95', 19||substr(ds_str_data_table,21,2)
                                                                          , '96', 19||substr(ds_str_data_table,21,2)
                                                                          , '97', 19||substr(ds_str_data_table,21,2)
                                                                          , '98', 19||substr(ds_str_data_table,21,2)
                                                                          , '99', 19||substr(ds_str_data_table,21,2)
                                                                          ,       20||substr(ds_str_data_table,21,2))) dt_fim
                        , substr(ds_str_data_table, 27,1)  travel
                        , substr(ds_str_data_table, 28,8)  geo_tbl_no
                        , substr(ds_str_data_table, 36,8)  date_tbl_no
                        , substr(ds_str_data_table, 44,8)  text_tbl_no
                        , substr(ds_str_data_table, 52,1)  unavail
                     FROM Batch_Category_Data_Table
                    WHERE nr_cat_data_table = p_nr_cat_data_table);

   r_cat3 c_dm%ROWTYPE;

BEGIN
   
   p_cd_processo := 'CAT3';
   p_cd_sistema  := 'GTP';
   IF p_nr_cat_data_table <> 3 THEN
      p_cd_retorno := 9999;
      p_ds_mensagem := ' CATEGORIA NÃO EXISTENTE!';
      raise_application_error(-20999,substr(p_cd_retorno ||' '||p_ds_mensagem,1,100));
   ELSE
      p_cd_retorno := 0;
   END IF;
                                                                      
      
   OPEN C_DM;
      LOOP
        
        n_cont := n_cont + 1;
         
         FETCH c_dm INTO r_cat3;
            EXIT WHEN c_dm%notfound;
             
                   
                         
            --- Cria um contantador para a tabela cat3_franklin ---     
            SELECT count(cod_cat3) + 1
               INTO n_cod_cat
               FROM Cat3_Franklin;
         
            BEGIN 
               INSERT INTO Cat3_Franklin
                         ( cod_cat3         , rec_tp            , action
                         , cat_no           , tbl_no            , tipe 
                         , dt_inicio        , dt_fim            , travel
                         , geo_tbl_no       , date_tbl_no       , text_tbl_no       , unavail
                         )
                    VALUES
                         ( n_cod_cat        , r_cat3.rec_type   , r_cat3.action
                         , r_cat3.cat_no    , r_cat3.tbl_no     , r_cat3.tipe 
                         , r_cat3.dt_ini    , r_cat3.dt_fim     , r_cat3.travel
                         , r_cat3.geo_tbl_no, r_cat3.date_tbl_no, r_cat3.text_tbl_no, r_cat3.unavail
                         );
               IF n_cont >= 5000 THEN
                 COMMIT;
                  n_cont := 0;
               END IF;
               
            EXCEPTION 
               WHEN OTHERS THEN
                  p_cd_retorno  := 9999;
                  p_ds_mensagem := SQLERRM;  
            END;        
            
      END LOOP;
         COMMIT;
   CLOSE C_DM;
END;

Tineks
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 365
Registrado em: Ter, 24 Mai 2005 2:24 pm
Localização: Araraquara - SP
Cristiano (Tineks)
Araraquara - SP

Nesse caso como você gostaria de parar seu process ou somente apresentar no final dele quais registros deram problema??

[]'s
franklin_kunioshi
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qui, 03 Jan 2008 9:24 am
Localização: São Paulo

Neste caso queria somente que ele converte-se a data
de 31 de fevereiro para 28 de fevereiro.
e também modificar todos os meses que não tem dia 31 para 30
até ai eu consegui
agora preciso debugar um erro de

v_ds_mensagem = ORA-01722: invalid number

vou mandar o codigo com esta agora

Obrigado pela ajuda!
franklin_kunioshi
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qui, 03 Jan 2008 9:24 am
Localização: São Paulo

Selecionar tudo

CREATE OR replace PROCEDURE proc_cat3 ( p_nr_cat_data_table  IN        VARCHAR2
                                      , p_cd_sistema             OUT   VARCHAR2
                                      , p_cd_processo            OUT   VARCHAR2
                                      , p_cd_retorno             OUT   NUMBER
                                      , p_ds_mensagem            OUT   VARCHAR2
                                      ) IS
   v_dia      VARCHAR2(2);
   v_mês      VARCHAR2(2);
   v_ano      VARCHAR2(4);
   d_dt_fim   DATE; 
   
   n_cod_cat NUMBER(15) := 0;
   n_cont    NUMBER(15) := 0;
   CURSOR c_dm IS (SELECT substr(ds_str_data_table, 1,1)  rec_type
                        , substr(ds_str_data_table, 2,1)  action
                        , substr(ds_str_data_table, 3,3)  cat_no
                        , substr(ds_str_data_table, 6,8)  tbl_no
                        , substr(ds_str_data_table, 14,1) tipe
                        , to_char(decode(substr(ds_str_data_table, 19,2),'  ','01',substr(ds_str_data_table, 19,2))) ||'/' ||
                          to_char(substr(ds_str_data_table, 17,2)) ||'/'||
                          to_char( decode( substr(ds_str_data_table, 15,2), '  ','1904'
                                                                          , '90', 19||substr(ds_str_data_table,15,2)
                                                                          , '91', 19||substr(ds_str_data_table,15,2)
                                                                          , '92', 19||substr(ds_str_data_table,15,2)
                                                                          , '93', 19||substr(ds_str_data_table,15,2)
                                                                          , '94', 19||substr(ds_str_data_table,15,2)
                                                                          , '95', 19||substr(ds_str_data_table,15,2)
                                                                          , '96', 19||substr(ds_str_data_table,15,2)
                                                                          , '97', 19||substr(ds_str_data_table,15,2)
                                                                          , '98', 19||substr(ds_str_data_table,15,2)
                                                                          , '99', 19||substr(ds_str_data_table,15,2)
                                                                          ,       20||substr(ds_str_data_table,15,2))) dt_ini
                        , to_char(decode(substr(ds_str_data_table, 25,2),'  ','31',substr(ds_str_data_table,25,2))) ||'/' ||
                          to_char(substr(ds_str_data_table, 23,2)) ||'/'||
                          to_char( decode( substr(ds_str_data_table, 21,2), '  ','1904'
                                                                          , '90', 19||substr(ds_str_data_table,21,2)
                                                                          , '91', 19||substr(ds_str_data_table,21,2)
                                                                          , '92', 19||substr(ds_str_data_table,21,2)
                                                                          , '93', 19||substr(ds_str_data_table,21,2)
                                                                          , '94', 19||substr(ds_str_data_table,21,2)
                                                                          , '95', 19||substr(ds_str_data_table,21,2)
                                                                          , '96', 19||substr(ds_str_data_table,21,2)
                                                                          , '97', 19||substr(ds_str_data_table,21,2)
                                                                          , '98', 19||substr(ds_str_data_table,21,2)
                                                                          , '99', 19||substr(ds_str_data_table,21,2)
                                                                          ,       20||substr(ds_str_data_table,21,2))) dt_fim
                        , substr(ds_str_data_table, 27,1)  travel
                        , substr(ds_str_data_table, 28,8)  geo_tbl_no
                        , substr(ds_str_data_table, 36,8)  date_tbl_no
                        , substr(ds_str_data_table, 44,8)  text_tbl_no
                        , substr(ds_str_data_table, 52,1)  unavail
                     FROM Batch_Category_Data_Table
                    WHERE nr_cat_data_table = p_nr_cat_data_table);

   r_cat3 c_dm%ROWTYPE;

BEGIN
   
   p_cd_processo := 'CAT3';
   p_cd_sistema  := 'GTP';
   IF p_nr_cat_data_table <> 3 THEN
      p_cd_retorno := 9999;
      p_ds_mensagem := ' CATEGORIA NÃO EXISTENTE!';
      raise_application_error(-20999,substr(p_cd_retorno ||' '||p_ds_mensagem,1,100));
   ELSE
      p_cd_retorno := 0;
   END IF;
                                                                      
      
   OPEN C_DM;
      LOOP
        
        n_cont := n_cont + 1;
         
         FETCH c_dm INTO r_cat3;
            EXIT WHEN c_dm%notfound;
               
                   
                --- Tratamento de erro para correção de data invalida ---
                   
                   IF substr(r_cat3.dt_fim,4,2)='02'  and substr(r_cat3.dt_fim,1,2) ='31' then
                      v_dia := '28';
                      v_mês := substr(r_cat3.dt_fim,4,2);
                      v_ano := substr(r_cat3.dt_fim,7,4);
                
                ELSIF substr(r_cat3.dt_fim,4,2) ='04' and substr(r_cat3.dt_fim,1,2) ='31' then
                      v_dia := '30';
                      v_mês := substr(r_cat3.dt_fim,4,2);
                      v_ano := substr(r_cat3.dt_fim,7,4);
       
                ELSIF substr(r_cat3.dt_fim,4,2) ='06' and substr(r_cat3.dt_fim,1,2) ='31' then
                      v_dia := '30';
                      v_mês := substr(r_cat3.dt_fim,4,2);
                      v_ano := substr(r_cat3.dt_fim,7,4);
       
                ELSIF substr(r_cat3.dt_fim,4,2) ='09' and substr(r_cat3.dt_fim,1,2) ='31' then
                      v_dia := '30';
                      v_mês := substr(r_cat3.dt_fim,4,2);
                      v_ano := substr(r_cat3.dt_fim,7,4);
       
                ELSIF substr(r_cat3.dt_fim,4,2) ='11' and substr(r_cat3.dt_fim,1,2) ='31' then
                      v_dia := '30';
                      v_mês := substr(r_cat3.dt_fim,4,2);
                      v_ano := substr(r_cat3.dt_fim,7,4);
                ELSE
                      v_dia := substr(r_cat3.dt_fim,1,2);
                      v_mês := substr(r_cat3.dt_fim,4,2);
                      v_ano := substr(r_cat3.dt_fim,7,4);
                END IF;    
                
                d_dt_fim:= TO_DATE(v_dia||'/'||v_mês||'/'||v_ano,'DD/MM/YYYY');
                
           --- Cria um contantador para a tabela cat3_franklin ---     
            SELECT count(cod_cat3) + 1
               INTO n_cod_cat
               FROM Cat3_Franklin;
         
            BEGIN 
               INSERT INTO Cat3_Franklin
                         ( cod_cat3         , rec_tp            , action
                         , cat_no           , tbl_no            , tipe 
                         , dt_inicio        , dt_fim            , travel
                         , geo_tbl_no       , date_tbl_no       , text_tbl_no       , unavail
                         )
                    VALUES
                         ( n_cod_cat        , r_cat3.rec_type   , r_cat3.action
                         , r_cat3.cat_no    , r_cat3.tbl_no     , r_cat3.tipe 
                         , r_cat3.dt_ini    , r_cat3.dt_fim     , r_cat3.travel
                         , r_cat3.geo_tbl_no, r_cat3.date_tbl_no, r_cat3.text_tbl_no, r_cat3.unavail
                         );
               IF n_cont >= 5000 THEN
                 COMMIT;
                  n_cont := 0;
               END IF;
               
            EXCEPTION 
               WHEN OTHERS THEN
                  p_cd_retorno  := 9999;
                  p_ds_mensagem := SQLERRM;  
            END;        
            
      END LOOP;
        COMMIT;
   CLOSE C_DM;
END;
/






eo erro que apresenta


Selecionar tudo

DV39>@c:\gtp\exec_proc3
v_cd_sistema  = GTP
v_cd_processo = CAT3
v_cd_retorno  = 9999
v_ds_mensagem = ORA-01722: invalid number

Procedimento PL/SQL concluído com sucesso.


Obrigado
Tineks
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 365
Registrado em: Ter, 24 Mai 2005 2:24 pm
Localização: Araraquara - SP
Cristiano (Tineks)
Araraquara - SP

Franklin, qual o tamanho da váriavel v_ds_mensagem ?

uma sugestão, do jeito que você tratou o último dia do mês não está errado, mas vai aqui uma dica pra você diminuir um pouco o seu código..

Selecionar tudo

SQL> DECLARE
  2     v_data_cursor   VARCHAR2 (100) := '31/02/2008';
  3     v_data          DATE;
  4  BEGIN
  5     BEGIN
  6        v_data := TO_DATE (v_data_cursor, 'DD/MM/YYYY');
  7     EXCEPTION
  8        WHEN OTHERS THEN
  9           v_data := LAST_DAY (TO_DATE ('01' || SUBSTR (v_data_cursor, 3, 8),'DD/MM/YYYY'));
 10     END;
 11     DBMS_OUTPUT.put_line ('Data : ' || v_data);
 12  END;
 13  
 14  /
Data : 29-FEB-08
nesse código tem um exception, caso de algum erro ele vai montar a data utilizando o last_day, dessa forma não importa a data que foi informada, se for inválida sempre vai pegar a última..

[]'s
franklin_kunioshi
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qui, 03 Jan 2008 9:24 am
Localização: São Paulo

entendo mais agora neste codigo ah data será somente transferida de outra tabela
mais o problema agora é essse erro que esta dando
preciso verificar qual o problema por meio de

DBMS tem ideia de como posso fazer

Obrigado
Tineks
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 365
Registrado em: Ter, 24 Mai 2005 2:24 pm
Localização: Araraquara - SP
Cristiano (Tineks)
Araraquara - SP

Tem como você ver o tamanho da váriavel v_ds_mensagem ?

[]'s
franklin_kunioshi
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qui, 03 Jan 2008 9:24 am
Localização: São Paulo

o tamanho (1000)
v_ds_mensagem!
gokden
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 264
Registrado em: Dom, 19 Ago 2007 8:18 pm
Localização: Ribeirão Preto - SP
Lucas de Souza

OCA Developer
Analista de sistemas

cara, se eu não me engano, o oracle já verifica a data...
ele nunca vai aceitar você dar um insert com a data 31 de fevereiro...

ele retorna um erro já...

Selecionar tudo

ORA-01839: date not valid for month specified
até se você for fazer um to_char com a data 31 de fevereiro ele retorna um erro...
Responder
  • Informação
  • Quem está online

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