SQL para leer XML del archivo en la base de datos PostgreSQL
12
¿Cómo puedo escribir SQL para leer un archivo XML en un XMLvalor PostgreSQL ?
PostgreSQL tiene un tipo de datos XML nativo con la XMLPARSEfunción de analizar una cadena de texto a ese tipo. También tiene formas de leer datos del sistema de archivos; el COPYcomunicado, entre otros.
Pero no veo una manera de escribir declaraciones SQL PostgreSQL nativas para leer el contenido de una entrada del sistema de archivos y usarlo para completar un XMLvalor. ¿Cómo puedo hacer esto?
Similar a esta respuesta a una pregunta anterior, y si no desea las restricciones depg_read_file() (en resumen: pg_read_fileno puede leer archivos fuera del directorio de la base de datos y lee el texto en la codificación de caracteres de la sesión actual).
Esta función funciona para cualquier ruta, pero debe crearse como superusuario:
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 se introdujo en 9.4, por lo que para versiones anteriores necesitaría:
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;$$;
Tiene limitaciones: nuevo en PostgreSQL 9.1 o superior; debe ser una sesión propiedad del superusuario de la base de datos; debe leer un archivo dentro del directorio de la base de datos o debajo. Esos son aceptables en mi caso de uso.
Entonces, lo siguiente funcionará para crear un XMLvalor nativo de un archivo:
-- PostgreSQL 9.1 or later.SELECT
XMLPARSE(DOCUMENT convert_from(
pg_read_binary_file('foo.xml'),'UTF8'));
En PostgreSQL 8.3 - 9.0, la pg_read_filefunción se puede utilizar, con la limitación adicional de que no puede especificar una codificación específica de archivo (lee el archivo como texto en la codificación de la sesión actual).
-- PostgreSQL earlier than 9.1.SELECT
XMLPARSE(DOCUMENT pg_read_file('foo.xml'));
pg_read_file()
. Lo mismo también se puede lograr con una tabla temporal yCOPY
- complete solo 1 columna de 1 fila.La
pg_read_binary_file
función puede hacer esto.Tiene limitaciones: nuevo en PostgreSQL 9.1 o superior; debe ser una sesión propiedad del superusuario de la base de datos; debe leer un archivo dentro del directorio de la base de datos o debajo. Esos son aceptables en mi caso de uso.
Entonces, lo siguiente funcionará para crear un
XML
valor nativo de un archivo:En PostgreSQL 8.3 - 9.0, la
pg_read_file
función se puede utilizar, con la limitación adicional de que no puede especificar una codificación específica de archivo (lee el archivo como texto en la codificación de la sesión actual).fuente
He publicado una implementación completa de lo que está pidiendo en una respuesta reciente sobre SO .
Las características clave son la
xpath()
función,pg_read_file()
manejo de matriz, funciones plpgsql, ..fuente