UTL_FILE.PUT_LINE erro na ultima linha

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
Avatar do usuário
bessa_lucas
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 55
Registrado em: Sex, 17 Out 2014 3:02 pm
Lucas Bessa
Analista de Sistemas

lucas.bessa@obers.com.br
lucas.bessa.ti@gmail.com

Pessoal,

Estou fazendo a integração via txt com outro sistema e estou com um problema ao ler o arquivo.
O código esta lendo normalmente, mas quando le a ultima linha e chega no comando "UTL_File.GET_LINE(arquivo,linha);" O código pula para o Exception when_other_then, porque não tem mais linhas para ler.

O arquivo pode vir com N quantidades de linhas

Tentei alterar o arquivo para colocar um "Enter" ao final, mas também não resolveu. Alguém tem alguma sugestão?

Selecionar tudo

          -- ABRE O ARQUIVO SELECIONADO
          arquivo := UTL_File.Fopen('INTEGRACAO_FABRICA_ORDEM',nome_arquivos,'r',32767);

          -- CONTA A QUANTIDADE DE ARQUIVOS
          X_CONTADOR:= X_CONTADOR + 1;
          
          SAVEPOINT inserir_importacao;
        
          -- LOOP PARA PERCORRER AS LINHAS DO ARQUIVO
          BEGIN
            LOOP
              
              UTL_File.GET_LINE(arquivo,linha);
      
              IF linha IS NULL THEN
                EXIT;
              END IF;
              
              sequencia             := extrair_valor_string(linha,';',1);
              produto               := extrair_valor_string(linha,';',2);
              formula               := extrair_valor_string(linha,';',3);
              materia_prima         := extrair_valor_string(linha,';',4);
              peso_programado       := extrair_valor_string(linha,';',5)/10000; -- CONVERSÃO PARA 4 CASAS DECIMAIS
              peso_real             := extrair_valor_string(linha,';',6)/10000; -- CONVERSÃO PARA 4 CASAS DECIMAIS
              data_hora_inicio      := extrair_valor_string(linha,';',7)||' '||extrair_valor_string(linha,';',8);
              data_hora_final       := extrair_valor_string(linha,';',9)||' '||extrair_valor_string(linha,';',10);
              lote_materia_prima    := extrair_valor_string(linha,';',11);
              silo                  := extrair_valor_string(linha,';',12);
              numero_bateladas      := extrair_valor_string(linha,';',13);
              
              -- SCRIPT PARA APARECER NO SQL DEVELOPER
              /*DBMS_OUTPUT.put('Sequencia: '             ||sequencia);
              DBMS_OUTPUT.put(' Produto: '              ||produto);
              DBMS_OUTPUT.put(' Formula: '              ||formula);
              DBMS_OUTPUT.put(' Materia Prima: '        ||materia_prima);
              DBMS_OUTPUT.put(' Peso programado: '      ||peso_programado);
              DBMS_OUTPUT.put(' Peso real: '            ||peso_real);
              DBMS_OUTPUT.put(' Data/Hora inicio: '     ||data_hora_inicio);
              DBMS_OUTPUT.put(' Data/Hora final: '      ||data_hora_final);
              DBMS_OUTPUT.put(' Lote materia prima: '   ||lote_materia_prima);
              DBMS_OUTPUT.put(' Silo: '                 ||silo);
              DBMS_OUTPUT.put_line(' Numero Bateladas: '||numero_bateladas);*/
      
              --FAZER INSERT NA TABELA TB_IMP_INTEGRACAO_FABRICA
              
              
               BEGIN
                 INSERT INTO TB_IMP_SISPROD 
                 (
                 NOME_ARQUIVO,
                 SEQUENCIA,
                 PRODUTO,
                 FORMULA,
                 MATERIA_PRIMA,
                 PESO_PROGRAMADO,
                 PESO_REAL,
                 INICIO,
                 FINAL,
                 LOTE,
                 SILO,
                 BATELADAS
                 )
                 VALUES
                 (
                  nome_arquivos,
                  sequencia,
                  produto,
                  formula,
                  materia_prima,
                  peso_programado,
                  peso_real,
                  to_date(data_hora_inicio, 'DD/MM/RR HH24:MI:SS'),
                  to_date(data_hora_final, 'DD/MM/RR HH24:MI:SS'),
                  lote_materia_prima,
                  silo,
                  numero_bateladas);
                 EXCEPTION
                    WHEN NO_DATA_FOUND THEN
                      retorno := 1;
                      --Dbms_Output.Put_Line('Dados não encontrados');
                    WHEN TOO_MANY_ROWS THEN
                      retorno := 1;
                      --dbms_output.put_line('Mais de uma linha');
               
               --COMMIT;       
               END;
      
               total := total + 1;
               END LOOP; -- FIM DO LOOP DE LEITURA DO ARQUIVO
               
              -- EXCEPTION DO ARQUIVO
                
                EXCEPTION
                   WHEN  utl_file.invalid_mode THEN
                      --Dbms_Output.Put_Line ('Parametro de modo inválido');
                      retorno := 2;
                      UTL_FILE.FCLOSE(arquivo);
                   WHEN  utl_file.invalid_path THEN
                      --Dbms_Output.Put_Line ('Localização de arquivo inválido');
                      UTL_FILE.FCLOSE(arquivo);
                      retorno := 2;
                   WHEN  utl_file.invalid_filehandle THEN
                      --Dbms_Output.Put_Line ('Identificador de arquivo inválido');
                      retorno := 2;
                      UTL_FILE.FCLOSE(arquivo);
                   WHEN  utl_file.invalid_operation THEN
                      --Dbms_Output.Put_Line ('Operação inválida');
                      retorno := 2;
                      UTL_FILE.FCLOSE(arquivo);
                   WHEN  utl_file.read_error THEN
                      --Dbms_Output.Put_Line ('Erro de leitura');
                      retorno := 2;
                      UTL_FILE.FCLOSE(arquivo);
                   WHEN  utl_file.internal_error THEN
                      --Dbms_Output.Put_Line ('Erro interno');
                      retorno := 2;
                      UTL_FILE.FCLOSE(arquivo);
                   WHEN  utl_file.charsetmismatch THEN
                      --Dbms_Output.Put_Line ('Arquivo aberto incompatível');
                      retorno := 2;
                      UTL_FILE.FCLOSE(arquivo);
                   WHEN  utl_file.file_open THEN
                      --Dbms_Output.Put_Line ('O arquivo já esta aberto');
                      retorno := 2;
                      UTL_FILE.FCLOSE(arquivo);
                   WHEN  utl_file.invalid_maxlinesize THEN
                      --Dbms_Output.Put_Line ('A linha excedeu o tamanho 32K');
                      retorno := 2;
                      UTL_FILE.FCLOSE(arquivo);
                   WHEN  utl_file.invalid_filename THEN
                      --Dbms_Output.Put_Line ('Nome do arquivo inválido');
                      retorno := 2;
                      UTL_FILE.FCLOSE(arquivo);
                   WHEN  utl_file.access_denied THEN
                      --Dbms_Output.Put_Line ('Acesso negado');
                      retorno := 2;
                      UTL_FILE.FCLOSE(arquivo);
                   WHEN OTHERS THEN
                      --Dbms_Output.Put_Line ('Erro desconhecido UTL.FILE');
                      --retorno := 2;
                      UTL_FILE.FCLOSE(arquivo);
               
              UTL_FILE.FCLOSE(arquivo);    
          END;    
BCR
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 25
Registrado em: Qui, 22 Nov 2012 1:40 pm
Localização: Patos de Minas
Breno Cristovão Rocha.

Lucas,

quando se usa o GET_LINE e ele lê uma linha em branco, ele gera uma string vazia.

-------------------------------------------------------------------------------------------------

A Procedure GET_LINE

Esta procedure lê uma linha de dados do arquivo especificado. Os dados lidos são armazenados na variável fornecida como parâmetro. A especificação para a procedure é:


PROCEDURE GET_LINE
(FILE_IN IN UTL_FILE.FILE_TYPE,
LINE OUT VARCHAR2);
O parâmetro "LINE" deve ser grande o suficiente para receber todos os dados até o primeiro sinal de retorno de carro (carriage return)ou de fim de arquivo, caso contrário será gerada a exception "VALUE_ERROR".

Se a procedure tentar ler depois do fim do arquivo será gerada a exception "NO_DATA_FOUND".

-----------------------------------------------------------------------------------------------------------------------------


Tente fazer um tratamento, fora do LOOP... lá nos exceptions....


WHEN NO_DATA_FOUND THEN
UTL_FILE.FCLOSE_ALL;


Quem sabe dê certo !
flws
Avatar do usuário
bessa_lucas
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 55
Registrado em: Sex, 17 Out 2014 3:02 pm
Lucas Bessa
Analista de Sistemas

lucas.bessa@obers.com.br
lucas.bessa.ti@gmail.com

Breno
O parâmetro "LINE" deve ser grande o suficiente para receber todos os dados até o primeiro sinal de retorno de carro (carriage return)ou de fim de arquivo, caso contrário será gerada a exception "VALUE_ERROR".
No meu exemplo a variável ele está com 32000, acredito que o problema não seja tamanho.
Tente fazer um tratamento, fora do LOOP... lá nos exceptions....

WHEN NO_DATA_FOUND THEN
UTL_FILE.FCLOSE_ALL;
Posso até adicionar o WHEN NO_DATA_FOUND, mas eu não queria que ao final da leitura ele não caísse no exception. :(
BCR
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 25
Registrado em: Qui, 22 Nov 2012 1:40 pm
Localização: Patos de Minas
Breno Cristovão Rocha.

Entendi...
a solução que imaginei foi no WHEN NO_DATA_FOUND...

se aparecer alguma ideia volto por aqui !

bratis
Responder
  • Informação