Pular para o conteúdo
Visualizando 10 posts - 1 até 10 (de 10 do total)
  • Autor
    Posts
  • #99256
    Doug
    Participante

      Pessoal, bom dia…

      Preciso escrever uma procedure na qual ira conter um campo do tipo long que ira gravar um arquivo txt com apenas uma linha e tamanho maior que 200K.

      O complicado é que o usuario precisa que essa informação seja inserida apenas em uma linha… e nao consigo gravar utilizando “put”.

      Alguma sugestão???

      #99257
      Doug
      Participante

        CREATE OR REPLACE PROCEDURE ESSAKAI.PRC_XML_BUILDER_v1p3(pCD_XML in number,
        pNM_ACAO in varchar2,
        pMSG out varchar2) IS

        vXML_Versao_Ausente boolean := true;
        in_file utl_file.file_type;
        linebuf varchar2(32767);
        filename varchar2(240);
        buf_lob CLOB;
        vMSG varchar2(240) default ‘Sucesso’;
        vnCounter number := 0;

        BEGIN
        filename := fun_XML_Nome_Arquivo(pNM_ACAO);
        if filename is not null then
        in_file := utl_file.fopen(‘DIR_XML_BFILE’, filename, ‘w’, 32767);

        BEGIN
        Declare
        — Documentos Assinados
        cursor c4 is
        select xdp.xdp_id_xct,
        xdp.xdp_id_cbr,
        substr(xdp.xdp_nm_doc, 1, length(xdp.xdp_nm_doc) – 4) xdp_nm_doc,
        xdp.xdp_doc_locator,
        xdp.xdp_doc_blob
        from hw_xml_docprotesto xdp;
        –where xdp.xdp_id_xct = pid_xct;

        vAuxc4 c4%rowtype;
        vQT_Carac pls_integer default 1024; — Quantidade de caracteres lidos de uma vez “Limitado ao tamanho do buffer 32767″
        vTT_Compr pls_integer; — Quantidade de caracteres do campo blob
        vNR_Grupo pls_integer := 0; — Parte inteira do Resultado de vTT_Compr dividido por vQT_Carac
        vQT_Resto pls_integer := 0; — Parte resto do Resultado de vTT_Compr dividido por vQT_Carac
        l_offset pls_integer default 1; — Ponteiro para início de leitura
        primeira_vez boolean := true;

        Begin
        open c4;
        fetch c4
        into vAuxc4;
        if c4%found then
        vTT_Compr := nvl(dbms_lob.getlength(vAuxc4.xdp_doc_blob), 0);
        vNR_Grupo := TRUNC(vTT_Compr / vQT_Carac);
        vQT_Resto := MOD(vTT_Compr, vQT_Carac);

        For i in 1 .. vNR_Grupo loop
        if primeira_vez then
        linebuf := linebuf ||
        dbms_lob.substr(vAuxc4.xdp_doc_blob,
        vQT_Carac,
        l_offset);
        primeira_vez := FALSE;
        else
        linebuf := dbms_lob.substr(vAuxc4.xdp_doc_blob,
        vQT_Carac,
        l_offset);
        end if;
        l_offset := l_offset + vQT_Carac;
        utl_file.put(in_file, linebuf); –alterado
        — utl_file.put(in_file, linebuf);
        linebuf := null;
        — utl_file.fflush(in_file);

        if i = 30 then
        exit;
        linebuf := null;
        end if;

        end loop;

        linebuf := dbms_lob.substr(vAuxc4.xdp_doc_blob,
        vQT_Resto – 2,
        l_offset);
        linebuf := linebuf || ‘” ‘;
        utl_file.put(in_file, linebuf);
        — utl_file.put ( in_file,linebuf ) ;
        linebuf := null;
        — utl_file.fflush(in_file);
        end if;
        close c4;
        /* Exception
        When UTL_FILE.INVALID_PATH then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 1 ‘||chr(10)||vMSG );
        When UTL_FILE.INVALID_MODE then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 2 ‘||chr(10)||vMSG );
        When UTL_FILE.INVALID_FILEHANDLE then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 3 ‘||chr(10)||vMSG );
        When UTL_FILE.INVALID_OPERATION then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 4 ‘||chr(10)||vMSG );
        When UTL_FILE.READ_ERROR then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 5 ‘||chr(10)||vMSG );
        When UTL_FILE.WRITE_ERROR then
        vMSG := sqlerrm;
        dbms_output.put_line( ‘Otre.: 6 ‘||chr(10)||vMSG );
        When UTL_FILE.INTERNAL_ERROR then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 7 ‘||chr(10)||vMSG );
        When UTL_FILE.INVALID_FILENAME then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 8 ‘||chr(10)||vMSG );
        When UTL_FILE.ACCESS_DENIED then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 9 ‘||chr(10)||vMSG );
        When UTL_FILE.INVALID_OFFSET then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 10 ‘||chr(10)||vMSG );
        When UTL_FILE.INVALID_MAXLINESIZE then vMSG := sqlerrm; dbms_output.put_line( ‘Otre.: 11 ‘||chr(10)||vMSG );
        When OTHERS then
        DBMS_OUTPUT.PUT_LINE(SUBSTR(SQLERRM,1,255));
        RAISE; */
        End;
        END DocProtesto;

        utl_file.fclose(in_file);
        else
        vMSG := ‘Não foi possível montar o nome do arquivo XML.’;
        end if;
        pMSG := vMSG;

        END PRC_XML_BUILDER_v1p3;

        #99264
        rman
        Participante

          Doug, o erro não está o no put.

          Fiz alguns testes, e dei umas pesquisadas, porque de inicio não fazia sentido dar erro.


          UTL_FILE.FOPEN (
          location IN VARCHAR2,
          filename IN VARCHAR2,
          open_mode IN VARCHAR2,
          max_linesize IN BINARY_INTEGER)
          RETURN file_type;

          max_linesize é o tamanho maximo de cada linha, incluindo o caracter de nova linha, logo temos 32767 bytes, que é igual a 31k menos 1b, max_linesize pode ir de 1 a 32767. Se não especificado o padrão é 1024.

          O erro acontece no UTL_FILE.FCLOSE. Ao fechar o arquivo a linha é maior que o suportado, então da erro de escrita.

          Como existe essa limitação de 31k menos 1b, não será possível por os 200k como desejado direto.

          Uma alternativa é abrir o arquivo inicialmente em modo ‘W’ fechar o arquivo em seguida abrir o arquivo em modo ‘A’ e fecha lo novamente, desta forma é só fazer um loop ate terminar a linha.

          Creio que a escrita no arquivo é feita no FCLOSE e não no PUT.

          Segue um teste que eu fiz:


          create or replace directory diretorio as 'c:temp';


          create or replace procedure prc_save_text_archive(directory in Varchar2,name_archive in Varchar2) is
          text_archive utl_file.file_type;
          text varchar(30720);
          trinta_k_bytes number;
          begin
          trinta_k_bytes := 30720;

             /*salvando 30k*/
             text_archive := utl_file.fopen(directory,name_archive,'w',32767);
          
             for i in 1..trinta_k_bytes
             loop
                 text := text || '1'  ;
             end loop;
          
             utl_file.put(text_archive,text);
          
             utl_file.fclose(text_archive);                  
          
             /*salvando 60k*/       
             text_archive := utl_file.fopen(directory,name_archive,'a',32767);
          
             text := null;
          
             for i in 1..trinta_k_bytes
             loop
                 text := text || '0'  ;
             end loop;
          
             utl_file.put(text_archive,text);
          
             utl_file.fclose(text_archive);       
          
             /*salvando 90k*/
             text_archive := utl_file.fopen(directory,name_archive,'a',32767);
          
             text := null;
          
             for i in 1..trinta_k_bytes
             loop
                 text := text || '1'  ;
             end loop;
          
             utl_file.put(text_archive,text);
          
             utl_file.fclose(text_archive);       
          

          end prc_save_text_archive;


          call prc_save_text_archive('DIRETORIO','TESTE.TXT');

          #99266
          Doug
          Participante

            Muito boa a explicação, mas me resta uma duvida…

            Ao inves de add os 0 na linha de baixo, eu consigo concatenar para ele fazer uma “tripa” só ?

            Ex : 11111111111111111111111100000000000000000000000011111111111111

            #99272
            rman
            Participante

              [quote=”Doug”:2ydh3dvo]Muito boa a explicação, mas me resta uma duvida…

              Ao inves de add os 0 na linha de baixo, eu consigo concatenar para ele fazer uma “tripa” só ?

              Ex : 11111111111111111111111100000000000000000000000011111111111111[/quote]

              Pootz, realmente eu não tinha me atentado, ao salvar o arquivo automaticamente é colocado CR e LF no final do arquivo. E o pior, não é o PUT que faz isso. A solução se baseava abrir o arquivo pela segunda vez em mode de APPEND e ir adicionando o restante da linha.

              A pergunta é ? É possível criar um arquivo texto sem o CR e LF no final do arquivo ? Eu não consegui…

              Tentei outra solução usando o FFLUSH, mas para descarregar os dados da memoria para o arquivo é necessario de um CR e LF também, apesar de não ter dado certo, segue o test, quem sabe alguém possa continuar a solução apartir deste ponto.


              create or replace procedure prc_save_text_archive(directory in varchar2,name_archive in varchar2) is
              text_archive utl_file.file_type;
              text varchar(30720);
              trinta_k_bytes number default 30720;
              begin
              text_archive := utl_file.fopen(directory,name_archive,'w',32767);

                 text := null;
              
                 for i in 1..trinta_k_bytes
                 loop
                     text := text || '0'  ;
                 end loop;
              
                 utl_file.put_line(text_archive,text);
              
                 utl_file.fflush(text_archive);                                                                            
              
                 text := replace(text,'0','1');
              
                 utl_file.put_line(text_archive,text);
              
                 utl_file.fflush(text_archive);                                                                            
              
                 text := replace(text,'1','0');
              
                 utl_file.put_line(text_archive,text);
              
                 utl_file.fflush(text_archive);                                                                            
              
                 utl_file.fclose(text_archive);              
              

              end prc_save_text_archive;

              #99273
              Doug
              Participante

                Aqui com fflush tbm nao deu certo…Por isso o desenvolvedor jogou o b.o pra mim, dizendo que pode ser algum patch da oracle.

                #99274
                rman
                Participante

                  [quote=”Doug”:1b8x686s]Aqui com fflush tbm nao deu certo…Por isso o desenvolvedor jogou o b.o pra mim, dizendo que pode ser algum patch da oracle.[/quote]

                  Pelo que eu andei lendo, um bug que existia era na hora de exportar BLOB para arquivo texto, onde o Oracle adicionada CR e LF no final do arquivo. Se fosse uma .GIF por exemplo a GIF era danificada. Creio que na versão atual esse bug já foi corrigido.

                  Por que essa geração de arquivo não é feita através de uma aplicação Delphi, Java, PHP, etc… ? Creio que é muito mais simples…

                  #99275
                  rman
                  Participante

                    Segue uma explicação do bug

                    http://www.idevelopment.info/data/Oracl … S_80.shtml

                    http://www.oracle-base.com/articles/9i/ExportBlob9i.php

                    O bug é em arquivo binario, mas o arquivo que você quer exportar é arquivo texto né ?

                    #99276
                    Doug
                    Participante

                      [quote=”rman”:2gi3x9ge]Segue uma explicação do bug

                      http://www.idevelopment.info/data/Oracl … S_80.shtml

                      http://www.oracle-base.com/articles/9i/ExportBlob9i.php

                      O bug é em arquivo binario, mas o arquivo que você quer exportar é arquivo texto né ?[/quote]

                      Sim , Sim..Arquivo texto….vou ler as explicacoes…

                      #99294
                      rman
                      Participante

                        E ai Doug !

                        Conseguiu resolver o problema ?

                        Qual a solução aplicada ?

                      Visualizando 10 posts - 1 até 10 (de 10 do total)
                      • Você deve fazer login para responder a este tópico.