SQL zum Lesen von XML aus einer Datei in eine PostgreSQL-Datenbank
12
Wie kann ich SQL schreiben, um eine XML-Datei in einen PostgreSQL- XMLWert zu lesen ?
PostgreSQL hat einen nativen XML-Datentyp mit der XMLPARSEFunktion, eine Textzeichenfolge auf diesen Typ zu analysieren. Es gibt auch Möglichkeiten, Daten aus dem Dateisystem zu lesen. die COPYAussage unter anderem.
Ich sehe jedoch keine Möglichkeit, native PostgreSQL-SQL-Anweisungen zu schreiben, um den Inhalt eines Dateisystemeintrags zu lesen und damit einen XMLWert aufzufüllen. Wie kann ich das machen?
Ähnlich wie bei dieser Antwort auf eine vorherige Frage, und wenn Sie die Einschränkungen vonpg_read_file() nicht möchten (kurz gesagt: pg_read_fileKann keine Dateien außerhalb des Datenbankverzeichnisses lesen und liest Text in der Zeichencodierung der aktuellen Sitzung).
Diese Funktion funktioniert für jeden Pfad, muss jedoch als Superuser erstellt werden:
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 wurde in 9.4 eingeführt, daher benötigen Sie für ältere Versionen:
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;$$;
Jack sagt, versuchen Sie es mit topanswers.xyz quelle
1
+1, danke, dass Sie darauf hingewiesen haben, dass die Funktionen zum Lesen von Dateien Beschränkungen unterliegen.
Bignose
1
+1 netter Trick zu umgehen pg_read_file(). Dasselbe kann auch mit einer temporären Tabelle erreicht werden und COPY- nur 1 Spalte von 1 Zeile ausfüllen.
Es gibt Einschränkungen: Neu in PostgreSQL 9.1 oder höher; muss eine Sitzung sein, die dem Datenbank-Superuser gehört; muss eine Datei innerhalb des Datenbankverzeichnisses oder darunter lesen. Diese sind in meinem Anwendungsfall akzeptabel.
Das Folgende funktioniert also, um einen nativen XMLWert aus einer Datei zu erstellen :
-- PostgreSQL 9.1 or later.SELECT
XMLPARSE(DOCUMENT convert_from(
pg_read_binary_file('foo.xml'),'UTF8'));
In PostgreSQL 8.3 - 9.0 kann die pg_read_fileFunktion verwendet werden, mit der zusätzlichen Einschränkung, dass Sie keine dateispezifische Codierung angeben können (die Datei wird als Text in der Codierung der aktuellen Sitzung gelesen).
-- PostgreSQL earlier than 9.1.SELECT
XMLPARSE(DOCUMENT pg_read_file('foo.xml'));
pg_read_file()
. Dasselbe kann auch mit einer temporären Tabelle erreicht werden undCOPY
- nur 1 Spalte von 1 Zeile ausfüllen.Die
pg_read_binary_file
Funktion kann dies tun.Es gibt Einschränkungen: Neu in PostgreSQL 9.1 oder höher; muss eine Sitzung sein, die dem Datenbank-Superuser gehört; muss eine Datei innerhalb des Datenbankverzeichnisses oder darunter lesen. Diese sind in meinem Anwendungsfall akzeptabel.
Das Folgende funktioniert also, um einen nativen
XML
Wert aus einer Datei zu erstellen :In PostgreSQL 8.3 - 9.0 kann die
pg_read_file
Funktion verwendet werden, mit der zusätzlichen Einschränkung, dass Sie keine dateispezifische Codierung angeben können (die Datei wird als Text in der Codierung der aktuellen Sitzung gelesen).quelle
Ich habe eine vollständige Implementierung dessen, wonach Sie fragen, in einer aktuellen Antwort auf SO veröffentlicht .
Die Hauptmerkmale sind die
xpath()
Funktionpg_read_file()
, Array-Handling, plpgsql-Funktionen, ..quelle