SQL pour lire XML du fichier dans la base de données PostgreSQL
12
Comment puis-je écrire du SQL pour lire un fichier XML dans une XMLvaleur PostgreSQL ?
PostgreSQL a un type de données XML natif avec la XMLPARSEfonction pour analyser une chaîne de texte vers ce type. Il a également des moyens de lire les données du système de fichiers; la COPYdéclaration, entre autres.
Mais je ne vois aucun moyen d'écrire des instructions SQL PostgreSQL natives pour lire le contenu d'une entrée de système de fichiers et l'utiliser pour remplir une XMLvaleur. Comment puis-je faire ceci?
Similaire à cette réponse à une question précédente, et si vous ne voulez pas les restrictions depg_read_file() (en bref: pg_read_filene peut pas lire les fichiers en dehors du répertoire de la base de données et lit le texte dans l'encodage des caractères de la session en cours).
Cette fonction fonctionne pour n'importe quel chemin, mais doit être créée en tant que superutilisateur:
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 a été introduit en 9.4, donc pour les anciennes versions, vous auriez besoin 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, merci d'avoir souligné qu'il y a des limites aux fonctions de lecture de fichiers.
bignose
1
+1 astuce à contourner pg_read_file(). La même chose peut également être obtenue avec une table temporaire et COPY- remplir seulement 1 colonne de 1 ligne.
Il a des limites: nouveau dans PostgreSQL 9.1 ou supérieur; doit être une session appartenant au superutilisateur de la base de données; doit lire un fichier dans le répertoire de la base de données ou en dessous. Celles-ci sont acceptables dans mon cas d'utilisation.
Ainsi, les éléments suivants fonctionneront pour créer une XMLvaleur native à partir d'un fichier:
-- PostgreSQL 9.1 or later.SELECT
XMLPARSE(DOCUMENT convert_from(
pg_read_binary_file('foo.xml'),'UTF8'));
Dans PostgreSQL 8.3 - 9.0, la pg_read_filefonction peut être utilisée, avec la limitation supplémentaire que vous ne pouvez pas spécifier un codage spécifique au fichier (il lit le fichier sous forme de texte dans le codage de la session en cours).
-- PostgreSQL earlier than 9.1.SELECT
XMLPARSE(DOCUMENT pg_read_file('foo.xml'));
pg_read_file()
. La même chose peut également être obtenue avec une table temporaire etCOPY
- remplir seulement 1 colonne de 1 ligne.La
pg_read_binary_file
fonction peut le faire.Il a des limites: nouveau dans PostgreSQL 9.1 ou supérieur; doit être une session appartenant au superutilisateur de la base de données; doit lire un fichier dans le répertoire de la base de données ou en dessous. Celles-ci sont acceptables dans mon cas d'utilisation.
Ainsi, les éléments suivants fonctionneront pour créer une
XML
valeur native à partir d'un fichier:Dans PostgreSQL 8.3 - 9.0, la
pg_read_file
fonction peut être utilisée, avec la limitation supplémentaire que vous ne pouvez pas spécifier un codage spécifique au fichier (il lit le fichier sous forme de texte dans le codage de la session en cours).la source
J'ai posté une implémentation complète de ce que vous demandez dans une réponse récente sur SO .
Les principales fonctionnalités sont la
xpath()
fonction, lapg_read_file()
gestion des tableaux, les fonctions plpgsql, ..la source