SQL para ler XML do arquivo no banco de dados PostgreSQL
12
Como escrever SQL para ler um arquivo XML em um XMLvalor do PostgreSQL ?
O PostgreSQL possui um tipo de dados XML nativo com a XMLPARSEfunção de analisar uma sequência de texto para esse tipo. Ele também tem maneiras de ler dados do sistema de arquivos; a COPYdeclaração, entre outros.
Mas não vejo uma maneira de escrever instruções SQL nativas do PostgreSQL para ler o conteúdo de uma entrada do sistema de arquivos e usá-la para preencher um XMLvalor. Como posso fazer isso?
Semelhante a esta resposta a uma pergunta anterior, e se você não quiser as restrições depg_read_file() (em resumo: pg_read_filenão pode ler arquivos fora do diretório do banco de dados e lê texto na codificação de caracteres da sessão atual).
Esta função funciona para qualquer caminho, mas precisa ser criada como superusuário:
createor replace function stack.bytea_import(p_path text, p_result out bytea)
language plpgsql as$$declare
l_oid oid;beginselect lo_import(p_path)into l_oid;select lo_get(l_oid)INTO p_result;
perform lo_unlink(l_oid);end;$$;
lo_get foi introduzido na 9.4, portanto, para versões mais antigas, você precisaria de:
createor replace function stack.bytea_import(p_path text, p_result out bytea)
language plpgsql as$$declare
l_oid oid;
r record;begin
p_result :='';select lo_import(p_path)into l_oid;for r in(select data
from pg_largeobject
where loid = l_oid
orderby pageno ) loop
p_result = p_result || r.data;end loop;
perform lo_unlink(l_oid);end;$$;
+1, obrigado por apontar que existem limites para as funções de leitura de arquivos.
precisa saber é
1
+1 truque legal para contornar pg_read_file(). O mesmo também pode ser alcançado com uma tabela temporária e COPY- preenche apenas 1 coluna de 1 linha.
Possui limitações: novo no PostgreSQL 9.1 ou superior; deve ser uma sessão pertencente ao superusuário do banco de dados; deve ler um arquivo no diretório do banco de dados ou abaixo. Esses são aceitáveis no meu caso de uso.
Portanto, o seguinte funcionará para criar um XMLvalor nativo a partir de um arquivo:
-- PostgreSQL 9.1 or later.SELECT
XMLPARSE(DOCUMENT convert_from(
pg_read_binary_file('foo.xml'),'UTF8'));
No PostgreSQL 8.3 - 9.0, a pg_read_filefunção pode ser usada, com a limitação adicional de que você não pode especificar uma codificação específica do arquivo (ele lê o arquivo como texto na codificação da sessão atual).
-- PostgreSQL earlier than 9.1.SELECT
XMLPARSE(DOCUMENT pg_read_file('foo.xml'));
pg_read_file()
. O mesmo também pode ser alcançado com uma tabela temporária eCOPY
- preenche apenas 1 coluna de 1 linha.A
pg_read_binary_file
função pode fazer isso.Possui limitações: novo no PostgreSQL 9.1 ou superior; deve ser uma sessão pertencente ao superusuário do banco de dados; deve ler um arquivo no diretório do banco de dados ou abaixo. Esses são aceitáveis no meu caso de uso.
Portanto, o seguinte funcionará para criar um
XML
valor nativo a partir de um arquivo:No PostgreSQL 8.3 - 9.0, a
pg_read_file
função pode ser usada, com a limitação adicional de que você não pode especificar uma codificação específica do arquivo (ele lê o arquivo como texto na codificação da sessão atual).fonte
Publiquei uma implementação completa do que você está solicitando em uma resposta recente ao SO .
Os principais recursos são a
xpath()
função,pg_read_file()
manipulação de array, funções plpgsql, ..fonte