Criação de arquivo TXT

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
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Pessoal,
Estou criando um arquivo de importação de edi, através de uns dados do oracle, porém estou com a seguinte dificuldade, tentarei explicar da forma mais clara possível:
Imaginem que eu tenha que gerar um arquivo TXT com 400 posições, porém eu só tenho 300 posições de dados, o resto deve ser completado com espaços.

No comando SELECT rpad(' ', 50, chr(32)) , o oracle acaba por não gerar todo o arquivo, ele simplismente ignora o retorno pois os dados são todos espaços.
Segue o comando inteiro que estou utilizando:

Selecionar tudo

set linesize 100000000000
set verify off
set head off
set feed off
set wrap on

col arquivo new_value arquivo

SELECT 'C:\PRE05' || TO_CHAR(SYSDATE, 'yyyymmddhhmmss') || '.txt' as arquivo
FROM DUAL;         

set termout on 
spool "&arquivo" 

select 'A' || -- OPERAÇÃO (01) ( VARCHAR ) -- OBRIGATÓRIO 
       rpad(a.numpedido, 30, ' ')|| -- REC_ORDER_CODE (30) ( VARCHAR ) -- OBRIGATÓRIO
       rpad(a.clmcl, 10, ' ')|| -- WAREHOUSE_CODE (10) ( VARCHAR ) -- OBRIGATÓRIO
       rpad(' ', 20, ' ')|| -- SUPPLIER_CODE (20) ( VARCHAR )
       rpad(' ', 20, ' ')|| -- CARRIER_CODE (20)  ( VARCHAR )
       rpad(a.numnf, 50, ' ')|| -- DOCUMENT (50) ( VARCHAR )
       rpad(' ', 50, ' ')|| -- TRANSPORT_TYPE (50) ( VARCHAR )
       rpad(' ', 50, ' ')|| -- MAIN_TRANSPORT (50) ( VARCHAR )
       rpad(' ', 50, ' ')|| -- AUX_TRANSPORT (50) ( VARCHAR )
       rpad(' ', 50, ' ')|| -- SOURCE (50) ( VARCHAR )
       rpad(a.tiporecebimento, 100, ' ')|| -- DESCRIPTION  (100) ( VARCHAR )
       rpad(' ', 14, ' ')|| --EXPECTED_DATE (14) ( DATE )
       rpad(' ', 17, ' ')|| --CONTAINERS (12,5) (NUMBER)
       rpad(' ', 30, ' ')|| --ORDER_TYPE (30) ( VARCHAR )
       rpad(' ', 12, ' ')|| --ACCOUNT_CODE (12) ( VARCHAR )
       rpad(' ', 50, ' ')|| --COMPANY (50)  ( VARCHAR )
       lpad(' ', 17, ' ')|| --DAYS_FROM_REC (12,5) ( NUMBER )
       rpad(' ', 12, ' ')|| --DOOR_CODE (12) ( VARCHAR )
       lpad(a.numlinha, 10, 0)|| -- num_linha (10) (NUMBER)
       chr(13)||--QUEBRA DE LINHA
       '/'|| --DETAIL_LINE_START (1) ( VARCHAR )  -- OBRIGATÓRIO
       rpad(a.sku, 50, ' ')|| --PRODUCT_CODE (50)  ( VARCHAR ) -- OBRIGATÓRIO
       lpad(a.quantidade, 17, 0)|| -- QUANTITY  (12,5) (NUMBER) -- OBRIGATÓRIO
       rpad(' ', 100, ' ')
  from custom_pre a;
  
  


SPOOL OFF;




Consegui ser claro?



Desde já, obrigado!!
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

Hummmm...

Então guterror, já pensou em criar um delimitador para separar os campos?

Eu costumo usar o "|" para separar os campos.

Depois, no programa que eu usar para processar este arquivo TEXTO (loader, external table, excel, etc) basta fazer o tratamento deste separador/delimitador.

A vantagem é que o arquivo texto gerado é bem menor, pois as linhas não precisam ocupar tantas colunas. Os delimitadores já fazem este trabalho.

É somente uma sugestão.

Abraços,

Sergio
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Então Sérgio, eu não posso usar nenhum tipo de separador, pois é uma importação de arquivo edi, cuja ele segue pela posição dos dados nos arquivos txt...

O comando que fiz, no retorno do select pelo oracle, em tése da certo, mas quando peço para ser gerado via spool, ele ignora o espaços em branco no fim do arquivo! :cry:
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

Oi guterror,

Esta informação eu encontrei em no ORACLE OTN FORUM https://forums.oracle.com/forums/thread ... D=10325095. Neste link, o moderador recomenda o uso do CHR(160) para gerar um caractere que é considerado na geração do TXT:
Ok for anyone else having the same problem as I am, I have found a solution to the problem. You can use CHR(160) "a non breaking space" to replace the existing ASCII space within your query.
CHR(160) is not removed by the xml and the spacing remains intact.
so your query column would look as follows:

Selecionar tudo

REPLACE(column, " ", CHR(160)) as data_column.
Hope this helps.
Cheers
user1829521


Não sei se ele pode ser aplicado em seu caso, mas não custaria nada fazer uma tentativa, alterando a sua querie para substituir os espaços em branco por este caracter:

Selecionar tudo

Ex:
.....
REPLACE(rpad(' ', 20, ' ')," ",CHAR(160))|| 
....
Abraços,

Sergio Coutinho
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Bom dia!
Vou fazer um teste e posto o resultado!
Obrigado!!
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Fiz um teste, porém sem sucesso! :(

Tentei também em ultima instância, criar um campo novo na tabela, sendo preenchido com valor de null, com isso usei um nvl para tentar substituir por espaços, mas não também!

To quase desistindo! :(
marlonpasquali
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 248
Registrado em: Sex, 06 Fev 2009 3:02 pm
Localização: ERECHIM - RS

Olá amigo,
eu já fiz diversos txt para integraçao com EDI e sempre usei dessa forma para gerar espaços em branco. Eu faço assim:

Selecionar tudo

Select
   rpad(a.customer_name,55,' ')       Nome,           -- nome do cliente
   rpad(' ',55,' ')                   Fantasia,       -- nome fantasia
   'C'                                Natureza,       -- natureza do endereço (cobrança)
   rpad(b.address1,70,' ')            Endereco,       -- endereço
   rpad(b.city,30,' ')                Cidade,         -- cidade
   b.state                            Estado,         -- estado
   rpad(replace(b.postal_code,'-',''),8,' ')  cep,            -- cep
   rpad(' ',4,' ')                    Area,
   rpad(' ',10,' ')                   Fone,
   rpad(' ',4,' ')                    DDDfax,
   rpad(' ',10,' ')                   Fax,
   rpad(' ',50,' ')                   email,

etc.....
att,
Marlon
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Marlon, tudo bem?

E como você gera os arquivos??
É via spool?

Obrigado
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Marlon,
O meu comando, eu já estou concatenando, para gerar via spool, segue um pequeno trecho, é desta forma que você estava acostumado a trabalhar?

Selecionar tudo

pad(a.numpedido, 30, ' ')|| 
rpad('LEVESUL', 10, ' ')||
rpad('TESTE', 20, ' ')|| 
rpad(' ', 20, ' ')
marlonpasquali
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 248
Registrado em: Sex, 06 Fev 2009 3:02 pm
Localização: ERECHIM - RS

Guterror,
na verdade eu sempre desenvolvo uma Procedure em PL/SQL onde eu tenho muito mais controle sobre a funcionalidade.
se quiser posso postar um exemplo aqui.

att,
Marlon
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Então Marlon...
Eu realmente preciso que seja gerado via arquivo txt...
O meu grande problema é realmente este, pois se fosse via procedure, o estava pronto, mas ao gerar o arquivo txt ele simplismente ignora os 'espaços' restantes.
marlonpasquali
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 248
Registrado em: Sex, 06 Fev 2009 3:02 pm
Localização: ERECHIM - RS

é dessa forma eu não tenho muita experiencia. Fiz um teste usando a linha abaixo mas não consegui apurar se o resultado ficou correto. Já tentou assim ?

rpad(CHR(160), 100, ' ')
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

Uma sugestão,

Coloque no final da sua querie com campos contatenados um delimitador fixo (ex: "|" ou "#").

Veja se ele preserva os espaços em branco nestas condições.

Se funcionar, então eu recomendaria adicionar sempre este último caracter e tratar o mesmo no programa de destino (que vai ler o TXT).

Ou você então gera este campo e posteriormente - com a ajuda de um programa, como ultraedit - substitue este caracter por espaço.

Abraços,

Sergio Coutinho
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

STCOUTINHO,
Bom dia.
Se eu colocar algum caracter no final do arquivo, ele preserva os espaços, porém não posso fazer isto, visto que além de meu cliente não possuir licença, o arquivo será disponibilizado em um ftp, cujo o mesmo é "lido" pelo programa de segundo em segundo, e correria um grande risco de o arquivo "passar" de forma equivocada...
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 já tentou...
Mas, segue uma dica abaixo:

Selecionar tudo

select rpad(nvl('teucampo', ' '), 60, '-') 
  from dual
Tenta trocar o 'teucampo' pelo campo da base de dados e, o hífel por um espaço ' ' se for o caso.
Fiz uns testes e gerou as posições.
Só não sei se interpretei corretamente o teu problema.
Qualquer coisa, manda pra gente.
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

Via sqlplus, deveria ser suficiente setar o linesize com o tamanho desejado (400 no caso).
Tente utilizar o

Selecionar tudo

set trim off
também.
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Oi Pessoal,
O meu problema é justamente esse, se eu substituir no final do arquivo por algum outro caracter dá certo, mas só espaço não.
De qualquer forma, como via sql dá certo, vou criar uma rotina para jogar direto dentro do banco.
Obrigado a todos e desculpe a demora em voltar aqui, tive uns problemas de saúde! =(
Valeu galera!
Responder
  • Informação
  • Quem está online

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