[firebase-br] procedure de leitura de arquivo txt
Carlos H. Cantu
listas em warmboot.com.br
Quarta Março 30 21:28:02 -03 2022
Pra sua procedure retornar as linhas vc teria que ter usado "for select" e
colocado o suspend dentro do loop, mas transformar seu select em procedure do
jeito que você fez não vai resolver o problema de 1024 iterações de uma CTE
recursiva, pois a CTE continuou existindo dentro da procedure.
Você vai ter que se livrar da CTE pra não ter essa limitação.
Você pode tentar fazer o parse usando uma variável do tipo blob textual e as
funções internas substring, position, etc. pra fazer o parse das informações,
mas tenha em mente que toda mudança no conteúdo dessa variável criará uma nova
cópia em memória, portanto, dependendo do tamanho dos dados, pode consumir muita
RAM a ponto de fazer SWAP no disco.
Outra opção (que não sei se é viável no seu caso, pois desconheço a estrutura do
arquivo) seria manter o arquivo em disco e acessá-lo através de uma external
table, como descrito no exemplo em https://www.firebase.com.br/artigo.php?id=403
[]s
Carlos H. Cantu
eBook Guia de Migração para o FB 4 - www.firebase.com.br/guiafb4.php
www.FireBase.com.br - www.firebirdnews.org - blog.firebase.com.br
jvl> bom tarde pessoal.
jvl> precisava fazer um PROCEDURE que leia um arquivo txt com delimitador e
jvl> me retorne a lista de dados.
jvl> com um select funciona belezinha, porem o txt fica limitado a 1024
jvl> interações. então precisava transformar em uma procedure... alguém tem
jvl> alguma ideia de como fazer ou alguém tem algo parecido? segue abaixo o
jvl> select funcionando, procedure que ainda não esta funcionando. segue
jvl> também txt de teste.
jvl> Select (funciona)
jvl> with recursive
jvl> p as (
jvl> select
jvl> iif(right(p.arq,2) <> p.lb, p.arq || p.lb, p.arq) arq,
jvl> p.delimitador,
jvl> p.lb
jvl> from (
jvl> select
jvl> cast(:pArq as blob sub_type text) arq,
jvl> cast(:pDelimitador as char(1)) delimitador,
jvl> cast(ascii_char(13)||ascii_char(10) as char(2)) lb
jvl> from rdb$database) p),
jvl> linha as (
jvl> select
jvl> 0 idx,
jvl> left(p.arq,position(p.lb, p.arq) - 1) txt,
jvl> substring(p.arq from position(p.lb, p.arq) + 2) restante
jvl> from p
jvl> union all
jvl> select
jvl> l.idx + 1,
jvl> left(l.restante,position(p.lb, l.restante) - 1) txt,
jvl> substring(l.restante from position(p.lb, l.restante) + 2) restante
jvl> from linha l, p
jvl> where l.restante <> ''
jvl> ),
jvl> coluna as (
jvl> select
jvl> l.idx idx_linha,
jvl> 1 idx,
jvl> left(l.txt, position(p.delimitador, l.txt) - 1) txt,
jvl> substring(l.txt from position(p.delimitador, l.txt) + 1) ||
jvl> p.delimitador restante
jvl> from linha l, p
jvl> union all
jvl> select
jvl> c.idx_linha,
jvl> c.idx + 1,
jvl> left(c.restante, position(p.delimitador, c.restante) - 1),
jvl> substring(c.restante from position(p.delimitador, c.restante) + 1)
jvl> from coluna c, p
jvl> where c.restante <> ''
jvl> )
jvl> select
jvl> max(iif(c.idx = 1,c.txt,null)) coluna1,
jvl> max(iif(c.idx = 2,c.txt,null)) coluna2,
jvl> max(iif(c.idx = 3,c.txt,null)) coluna3
jvl> from coluna c
where c.idx_linha >> 0
jvl> group by c.idx_linha
jvl> Procedure (não funcional)
jvl> CREATE OR ALTER procedure SP_TESTE (
jvl> PARQ blob sub_type 1 segment size 80,
jvl> PDELIMITADOR char(1))
jvl> returns (
jvl> COL1 integer)
jvl> as
jvl> begin
jvl> with recursive
jvl> p as (
jvl> select
jvl> iif(right(p.arq,2) <> p.lb, p.arq || p.lb, p.arq) arq,
jvl> p.delimitador,
jvl> p.lb
jvl> from (
jvl> select
jvl> cast(:pArq as blob sub_type text) arq,
jvl> cast(:pDelimitador as char(1)) delimitador,
jvl> cast(ascii_char(13)||ascii_char(10) as char(2)) lb
jvl> from rdb$database) p ),
jvl> linha as (
jvl> select
jvl> 0 idx,
jvl> left(p.arq,position(p.lb, p.arq) - 1) txt,
jvl> substring(p.arq from position(p.lb, p.arq) + 2) restante
jvl> from p
jvl> union all
jvl> select
jvl> l.idx + 1,
jvl> left(l.restante,position(p.lb, l.restante) - 1) txt,
jvl> substring(l.restante from position(p.lb, l.restante) + 2) restante
jvl> from linha l, p
jvl> where l.restante <> ''
jvl> ),
jvl> coluna as (
jvl> select
jvl> l.idx idx_linha,
jvl> 1 idx,
jvl> left(l.txt, position(p.delimitador, l.txt) - 1) txt,
jvl> substring(l.txt from position(p.delimitador, l.txt) + 1) ||
jvl> p.delimitador restante
jvl> from linha l, p
jvl> union all
jvl> select
jvl> c.idx_linha,
jvl> c.idx + 1,
jvl> left(c.restante, position(p.delimitador, c.restante) - 1),
jvl> substring(c.restante from position(p.delimitador, c.restante) + 1)
jvl> from coluna c, p
jvl> where c.restante <> ''
jvl> )
jvl> select
jvl> max(iif(c.idx = 1,c.txt,null)) coluna1--,
jvl> -- max(iif(c.idx = 2,c.txt,null)) coluna2,
jvl> -- max(iif(c.idx = 3,c.txt,null)) coluna3
jvl> from coluna c
jvl> where c.idx_linha > 0
jvl> group by c.idx_linha
jvl> into :col1;--, :col2, :col3;
jvl> suspend;
jvl> end
jvl> desde já agradeço pela atenção
Mais detalhes sobre a lista de discussão lista