[firebase-br] procedure de leitura de arquivo txt

jonathan em pontualsis.com.br jonathan em pontualsis.com.br
Quarta Março 30 17:05:08 -03 2022


bom tarde pessoal.

precisava fazer um PROCEDURE que leia um arquivo txt com delimitador e
me retorne a lista de dados.

com um select funciona belezinha, porem o txt fica limitado a 1024
interações. então precisava transformar em uma procedure... alguém tem
alguma ideia de como fazer ou alguém tem algo parecido? segue abaixo o
select funcionando, procedure que ainda não esta funcionando. segue
também txt de teste.

Select (funciona)

with recursive
p as (
 select
 iif(right(p.arq,2) <> p.lb, p.arq || p.lb, p.arq) arq,
 p.delimitador,
 p.lb
 from (
 select
 cast(:pArq as blob sub_type text) arq,
 cast(:pDelimitador as char(1)) delimitador,
 cast(ascii_char(13)||ascii_char(10) as char(2)) lb
 from rdb$database) p), 

linha as (
 select
 0 idx,
 left(p.arq,position(p.lb, p.arq) - 1) txt,
 substring(p.arq from position(p.lb, p.arq) + 2) restante
 from p 

union all 

select
 l.idx + 1,
 left(l.restante,position(p.lb, l.restante) - 1) txt,
 substring(l.restante from position(p.lb, l.restante) + 2) restante
 from linha l, p
 where l.restante <> ''
), 

coluna as (
 select
 l.idx idx_linha,
 1 idx,
 left(l.txt, position(p.delimitador, l.txt) - 1) txt,
 substring(l.txt from position(p.delimitador, l.txt) + 1) ||
p.delimitador restante
 from linha l, p 

union all 

select
 c.idx_linha,
 c.idx + 1,
 left(c.restante, position(p.delimitador, c.restante) - 1),
 substring(c.restante from position(p.delimitador, c.restante) + 1)
 from coluna c, p
 where c.restante <> ''
) 

select
 max(iif(c.idx = 1,c.txt,null)) coluna1,
 max(iif(c.idx = 2,c.txt,null)) coluna2,
 max(iif(c.idx = 3,c.txt,null)) coluna3
from coluna c
where c.idx_linha > 0
group by c.idx_linha 

Procedure (não funcional) 

CREATE OR ALTER procedure SP_TESTE (
 PARQ blob sub_type 1 segment size 80,
 PDELIMITADOR char(1))
returns (
 COL1 integer)
as
begin
 with recursive
 p as (
 select
 iif(right(p.arq,2) <> p.lb, p.arq || p.lb, p.arq) arq,
 p.delimitador,
 p.lb
 from (
 select
 cast(:pArq as blob sub_type text) arq,
 cast(:pDelimitador as char(1)) delimitador,
 cast(ascii_char(13)||ascii_char(10) as char(2)) lb
 from rdb$database) p ),

 linha as (
 select
 0 idx,
 left(p.arq,position(p.lb, p.arq) - 1) txt,
 substring(p.arq from position(p.lb, p.arq) + 2) restante
 from p

 union all

 select
 l.idx + 1,
 left(l.restante,position(p.lb, l.restante) - 1) txt,
 substring(l.restante from position(p.lb, l.restante) + 2) restante
 from linha l, p
 where l.restante <> ''
 ),

 coluna as (
 select
 l.idx idx_linha,
 1 idx,
 left(l.txt, position(p.delimitador, l.txt) - 1) txt,
 substring(l.txt from position(p.delimitador, l.txt) + 1) ||
p.delimitador restante
 from linha l, p

 union all

 select
 c.idx_linha,
 c.idx + 1,
 left(c.restante, position(p.delimitador, c.restante) - 1),
 substring(c.restante from position(p.delimitador, c.restante) + 1)
 from coluna c, p
 where c.restante <> ''
 )
 select
 max(iif(c.idx = 1,c.txt,null)) coluna1--,
 -- max(iif(c.idx = 2,c.txt,null)) coluna2,
 -- max(iif(c.idx = 3,c.txt,null)) coluna3
 from coluna c
 where c.idx_linha > 0
 group by c.idx_linha 

into :col1;--, :col2, :col3; 

suspend; 

end 

desde já agradeço pela atenção
-------------- Próxima Parte ----------
NUMERO_NOTAFISCAL|CODIGO_PRODUTO|CODIGO_USUARIO_PALM
792.045|2.475|1
792.045|9.689|1
792.304|603|1
792.304|652|1
792.304|653|1
792.304|2.676|1
792.304|5.791|1
792.335|2.676|1
792.379|2.130|1
792.379|5.586|1
792.379|5.654|1
792.379|5.655|1
792.380|2.130|1
792.380|4.794|1
792.381|5.169|1
-------------- Próxima Parte ----------
NUMERO_NOTAFISCAL|CODIGO_PRODUTO|CODIGO_USUARIO_PALM
792.045|2.475|1
792.045|9.689|1
792.304|603|1
792.304|652|1
792.304|653|1
792.304|2.676|1
792.304|5.791|1
792.335|2.676|1
792.379|2.130|1
792.379|5.586|1
792.379|5.654|1
792.379|5.655|1
792.380|2.130|1
792.380|4.794|1
792.381|5.169|1


Mais detalhes sobre a lista de discussão lista