Gravar arquivo .TXT com linhas diferentes

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
Dezoti
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 14
Registrado em: Ter, 26 Nov 2013 1:27 pm
Localização: Fortaleza - CE

Pessoal, boa tarde

Estou trabalhando com PLSQL, porém ainda sou novato na área, e estou com uma certa dificuldade com importação de arquivos txt.
No caso, eu consigo ler e exibir as linhas do arquivo, porém o arquivo que eu vou receber se trata de 3 tipos de linhas diferentes (demografico, paciente, exames).
Ou seja, tem campos que estão recebendo o mesmo registro, pelo fato do UTL_File ao saltar de linha voltar a alimentar os campos novamente.

Gostaria de alguma dica de como posso ajustar meu código, lembrando que os campos que irei gravar dados diferentes são c_campo_5, c_campo_6 e c_campo_7.

Segue meu código:

Selecionar tudo

declare

    entrada_b2b_cerba         UTL_File.File_Type := utl_file.fopen('Caminho','arquivo.TXT','r');  
    linha                     varchar2(1000);
    c_campo_1                 varchar2(05);
    c_campo_2                 varchar2(04);
    c_campo_3                 varchar2(10);
    c_campo_4                 varchar2(01);
    c_campo_5                 varchar2(100);
    c_campo_5_1               varchar2(20);
    c_campo_5_2               varchar2(20);
    c_campo_6                 varchar2(08);
    c_campo_7                 varchar2(50);
    c_campo_8                 varchar2(05);
    posicao                   number  (30);    
    eof                       boolean := false; -- FLAG QUE INDICA FIM DO ARQUIVO.
    
   
  
      begin
        -- ARMAZENA A LINHA DO ARQUIVO NA VARIÁVEL 'linha'
        
         
          while not(eof) loop
          
         -- posicao := INSTR(linha, '#');
          begin
            utl_file.get_line(entrada_b2b_cerba,linha); 

          posicao      := instr(linha,'#');
          c_campo_1    := substr(linha,1,posicao - 1);
          linha        := substr(linha,posicao + 1);
          
          posicao      := instr(linha,'#');
          c_campo_2    := substr(linha,1,posicao - 1);
          linha        := substr(linha,posicao + 1);
          
          posicao      := instr(linha,'#');
          c_campo_3    := substr(linha,1,posicao - 1);
          linha        := substr(linha,posicao + 1);
          
          posicao      := instr(linha,'#');
          c_campo_4    := substr(linha,1,posicao - 1);
          linha        := substr(linha,posicao + 1);
          
          posicao      := instr(linha,'-');
          c_campo_5_1  := substr(linha,1,posicao - 1);
          linha        := substr(linha,posicao + 1);
          
          posicao      := instr(linha,'-');
          c_campo_5_2  := substr(linha,1,posicao - 1);
          
          posicao      := instr(linha,'#');  -- 53423-75489-19359781
          c_campo_5    := substr(linha,1,posicao - 1);
          linha        := substr(linha,posicao + 1);
          
          posicao      := instr(linha,'#');
          c_campo_6    := substr(linha,1,posicao - 1);
          linha        := substr(linha,posicao + 1);
          
          posicao      := instr(linha,'#');
          c_campo_7   := substr(linha,1,posicao - 1);
          linha        := substr(linha,posicao + 13);
          
          posicao      := instr(linha,'#');
          c_campo_8    := substr(linha,1,posicao - 1);
          linha        := substr(linha,posicao + 1);
          

        exception

         when no_data_found then
             eof := true;

         when others then
             Raise_Application_Error(-20000,'ERRO: ' || SQLERRM);
             
         end;
dbms_output.put_line(c_campo_1);
dbms_output.put_line(c_campo_2);
dbms_output.put_line(c_campo_3);
dbms_output.put_line(c_campo_4);
dbms_output.put_line(c_campo_5_1);
dbms_output.put_line(c_campo_5_2);
dbms_output.put_line(c_campo_5);
dbms_output.put_line(c_campo_6);
dbms_output.put_line(c_campo_7);
dbms_output.put_line(c_campo_8);

end loop;
end;

Agradeço desde já por qualquer dica que será muito bem vinda.
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

Aqui neste link tem a função ELEMENTO, que ajuda no caso de buscar campos delimitados.
Veja se ajuda!

viewtopic.php?p=4836#p4836
gledson.veras
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Ter, 10 Dez 2013 10:03 am

Cara, poderia postar seu layout para entendermos melhor?

Pelo que eu entendi, você teria um arquivo assim:



Selecionar tudo

DEMOGRAFICOYYYYYYYYYYYYYYYYYYYYYYYYY
PACIENTESXXXXXXXXXXXXXXXXXXXXXXXXXXX
EXAMESXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Se fosse como no exemplo acima, você teria um identificador de cada linha, ou seja, poderia atraves de IFs redirecionar a informacao.

Selecionar tudo

IF V_IDENTIFICADOR = 'DEMOGRAFICO' THEN

  PREENCHE VARIAVEL X
  
ELSIF V_IDENTIFICADOR = 'PACIENTES' THEN

  PREENCHE VARIAVEL Y

END IF
A não ser que o layout dos tres seja igual, o que eu acho improvável, você tavez consiga achar algo que identifique cada linha.
Avatar do usuário
Dezoti
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 14
Registrado em: Ter, 26 Nov 2013 1:27 pm
Localização: Fortaleza - CE

Opa, segue aqui uma parte do arquivo txt (complementando, os registros são representados assim: Demográfico é o D, Pacientes é o H e Exames é o P, sendo que o verificador é o quarto campo de cada linha):

Selecionar tudo

^CCPb#2626#37489428#D#53430-25565-19359816#20130312##############06:44#
^CCPb#2626#37489428#H#BRYAN SILVA#1#20090217#
^CCPb#2626#37489428#P#F14###
^CCPb#2626#37489428#P#F2###
^CCPb#2626#37489428#P#F245###
^CCPb#2626#37489428#P#F3###
^CCPb#2626#37489428#P#F4.###
Os separadores são os #, onde o campo ^CCPb é o indicador de segmento e é sempre o mesmo para todas as linhas.
Eu gero estes dados para 3 tabelas distintas (D, H e P) onde delas eu extraio o conteúdo, gero um um TXT com um período de exames e envio ao Laboratório, onde eles irão devolver no mesmo formato, porém terei de gravar o retorno em uma unica tabela separada.
gledson.veras
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Ter, 10 Dez 2013 10:03 am

Certo, então, no caso depois que você le a variavel 4, você já tem seu identificador, podendo redirecionar a informação.


Veja esse código e altere caso precise, eu não sei se as informaçoes que você postou estao em ordem.

Selecionar tudo

DECLARE
 V_LINHA VARCHAR2(4000);
 V_IN_FILE UTL_FILE.FILE_TYPE;
 V_CONTADOR NUMBER:=0;
 V_CONTADOR_LIDOS NUMBER:=0;
 V_PONTO VARCHAR2 (50);
 --
 V_DIRETORIO VARCHAR2(100):= 'Caminho';
 V_ARQUIVO VARCHAR2(100):= 'arquivo.txt';
 --
 V_campo_1 varchar2 (5);
 V_campo_2 varchar2 (4);
 V_campo_3 varchar2 (10);
 V_campo_4 varchar2 (1);
 V_campo_5 varchar2 (100);
 V_campo_5_1 varchar2 (20);
 V_campo_5_2 varchar2 (20);
 V_campo_6 varchar2 (8);
 V_campo_7 varchar2 (50);
 V_campo_8 varchar2 (5);
--
BEGIN
--
  BEGIN
  --
  V_IN_FILE:= UTL_FILE.FOPEN(LOCATION     => V_DIRETORIO,
                             FILENAME     => V_ARQUIVO,
                             OPEN_MODE    => 'R',
                             MAX_LINESIZE => 32767);
  --
  EXCEPTION
    WHEN UTL_FILE.INVALID_PATH THEN
      RAISE_APPLICATION_ERROR(-20010,'ERRO NA ABERTURA DO ARQUIVO. CAMINHO INVALIDO.');
    WHEN UTL_FILE.INVALID_MODE THEN
      RAISE_APPLICATION_ERROR(-20020,'ERRO NA ABERTURA DO ARQUIVO. MODO DE ABERTURA INVALIDO.');
    WHEN UTL_FILE.INVALID_OPERATION THEN
      RAISE_APPLICATION_ERROR(-20030,'ERRO NA ABERTURA DO ARQUIVO. OPERACAO INVALIDA.');
    WHEN OTHERS THEN
      RAISE_APPLICATION_ERROR(-20040,'ERRO NA ABERTURA DO ARQUIVO. ERRO GERAL.'||SQLERRM);
  END;
  IF UTL_FILE.IS_OPEN (V_IN_FILE) THEN
     --
     UTL_FILE.GET_LINE(V_IN_FILE, V_LINHA) ;
     --
     LOOP
       --
       BEGIN
         --
         V_LINHA := NULL ;
         UTL_FILE.GET_LINE(V_IN_FILE, V_LINHA) ;
         IF V_LINHA IS NULL THEN
            EXIT ;
         END IF ;
         --
       EXCEPTION
         WHEN OTHERS THEN
           EXIT ;
       END;
       --
       V_CONTADOR_LIDOS    := V_CONTADOR_LIDOS + 1 ;
       V_LINHA       := V_LINHA ||';' ;
       --
       BEGIN
       --> LEITURA DAS VARIAVEIS
         V_PONTO := 'CAMPO_1';
         V_CAMPO_1:= RTRIM(SUBSTR(V_LINHA, 1, INSTR(V_LINHA, ';') -1 )) ;
         V_LINHA := SUBSTR(V_LINHA, INSTR(V_LINHA, ';') +1 );
         --
         V_PONTO := 'CAMPO_2';
         V_CAMPO_2:= RTRIM(SUBSTR(V_LINHA, 1, INSTR(V_LINHA, ';') -1 )) ;
         V_LINHA := SUBSTR(V_LINHA, INSTR(V_LINHA, ';') +1 );
         --
         V_PONTO := 'CAMPO_3';
         V_CAMPO_3:= RTRIM(SUBSTR(V_LINHA, 1, INSTR(V_LINHA, ';') -1 )) ;
         V_LINHA := SUBSTR(V_LINHA, INSTR(V_LINHA, ';') +1 );
         --
         V_PONTO := 'CAMPO_4';
         V_CAMPO_4:= RTRIM(SUBSTR(V_LINHA, 1, INSTR(V_LINHA, ';') -1 )) ;
         V_LINHA := SUBSTR(V_LINHA, INSTR(V_LINHA, ';') +1 );
         
         --> INICIO DOS TRATAMENTOS         
         
         IF V_CAMPO_4 = 'D' THEN --DEMOGRAFICO
         
           V_PONTO := 'CAMPO_5';
           V_CAMPO_5:= RTRIM(SUBSTR(V_LINHA, 1, INSTR(V_LINHA, ';') -1 )) ;
           V_LINHA := SUBSTR(V_LINHA, INSTR(V_LINHA, ';') +1 );
           --
           V_PONTO := 'CAMPO_5_1';
           V_CAMPO_5_1:= RTRIM(SUBSTR(V_LINHA, 1, INSTR(V_LINHA, ';') -1 )) ;
           V_LINHA := SUBSTR(V_LINHA, INSTR(V_LINHA, ';') +1 );
           --
           V_PONTO := 'CAMPO_5_2';
           V_CAMPO_5_2:= RTRIM(SUBSTR(V_LINHA, 1, INSTR(V_LINHA, ';') -1 )) ;
           V_LINHA := SUBSTR(V_LINHA, INSTR(V_LINHA, ';') +1 );
         --
         ELSIF V_CAMPO_4 = 'H' THEN  --PACIENTE    
         
           V_PONTO := 'CAMPO_6';
           V_CAMPO_6:= RTRIM(SUBSTR(V_LINHA, 1, INSTR(V_LINHA, ';') -1 )) ;
           V_LINHA := SUBSTR(V_LINHA, INSTR(V_LINHA, ';') +1 );
         
         ELSIF V_CAMPO_4 = 'P' THEN    --EXAMES
         --
           V_PONTO := 'CAMPO_7';
           V_CAMPO_7:= RTRIM(SUBSTR(V_LINHA, 1, INSTR(V_LINHA, ';') -1 )) ;
           V_LINHA := SUBSTR(V_LINHA, INSTR(V_LINHA, ';') +1 );
         
         END IF;
         --
         V_PONTO := 'CAMPO_8';
         V_CAMPO_8:= RTRIM(SUBSTR(V_LINHA, 1, INSTR(V_LINHA, ';') -1 )) ;
         V_LINHA := SUBSTR(V_LINHA, INSTR(V_LINHA, ';') +1 );
         --
       EXCEPTION
         WHEN OTHERS THEN
           DBMS_OUTPUT.put_line('ERRO. PONTO: '||V_PONTO||' - '||SQLERRM);
           DBMS_OUTPUT.put_line('Tentou Ler: "'||SUBSTR(V_LINHA, INSTR(V_LINHA, ';') +1)||'"');
           DBMS_OUTPUT.put_line('Linha: "'||V_LINHA||'"');
           RAISE_APPLICATION_ERROR(-20001,'ERRO. PONTO: '||V_PONTO||' - '||SQLERRM);
       END;
       --

     END LOOP;
   END IF;
   --
--
DBMS_OUTPUT.PUT_LINE('--');
DBMS_OUTPUT.PUT_LINE('Registros Lidos: '||V_CONTADOR_LIDOS);
DBMS_OUTPUT.PUT_LINE('Registros Gravados: '||V_CONTADOR);
DBMS_OUTPUT.PUT_LINE('--');
--
EXCEPTION
  WHEN OTHERS THEN
    RAISE_APPLICATION_ERROR(-20001,'ERRO: '||SQLERRM);
END;
--
gledson.veras
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Ter, 10 Dez 2013 10:03 am

No seu caso troque o ";" pelo separador "#"

trocar

Selecionar tudo

    V_CAMPO_6:= RTRIM(SUBSTR(V_LINHA, 1, INSTR(V_LINHA, ';') -1 )) ;
           V_LINHA := SUBSTR(V_LINHA, INSTR(V_LINHA, ';') +1 );
por

Selecionar tudo

     V_CAMPO_6:= RTRIM(SUBSTR(V_LINHA, 1, INSTR(V_LINHA, '#') -1 )) ;
           V_LINHA := SUBSTR(V_LINHA, INSTR(V_LINHA, '#') +1 );
Avatar do usuário
Dezoti
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 14
Registrado em: Ter, 26 Nov 2013 1:27 pm
Localização: Fortaleza - CE

Só passando aqui para agradecer a ajuda que tive na época, acabei me esquecendo de responder e pôde parecer ingratidão.

Grande abraço.
Responder
  • Informação
  • Quem está online

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