SQL untuk membaca XML dari file ke dalam database PostgreSQL

12

Bagaimana saya bisa menulis SQL untuk membaca file XML menjadi XMLnilai PostgreSQL ?

PostgreSQL memiliki tipe data XML asli dengan XMLPARSEfungsi untuk mem-parsing string teks ke tipe itu. Ini juga memiliki cara untuk membaca data dari sistem file; yang COPYpernyataan, antara lain.

Tapi saya tidak melihat cara untuk menulis pernyataan SQL PostgreSQL asli untuk membaca konten dari entri sistem file dan menggunakannya untuk mengisi XMLnilai. Bagaimana saya bisa melakukan ini?

hidung besar
sumber

Jawaban:

10

Mirip dengan jawaban ini untuk pertanyaan sebelumnya, dan jika Anda tidak ingin pembatasanpg_read_file() (singkatnya: pg_read_filetidak dapat membaca file di luar direktori database, dan membaca teks dalam pengkodean karakter sesi saat ini).

Fungsi ini berfungsi untuk semua jalur, tetapi harus dibuat sebagai superuser:

create or replace function stack.bytea_import(p_path text, p_result out bytea) 
                   language plpgsql as $$
declare
  l_oid oid;
begin
  select lo_import(p_path) into l_oid;
  select lo_get(l_oid) INTO p_result;
  perform lo_unlink(l_oid);
end;$$;

lo_get diperkenalkan di 9.4 jadi untuk versi yang lebih lama Anda perlu:

create or 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 
             order by pageno ) loop
    p_result = p_result || r.data;
  end loop;
  perform lo_unlink(l_oid);
end;$$;

kemudian:

select convert_from(stack.bytea_import('/tmp/test.xml'), 'utf8')::xml;
Jack mengatakan coba topanswers.xyz
sumber
1
+1, terima kasih telah menunjukkan bahwa ada batasan untuk fungsi membaca file.
bignose
1
+1 trik yang bagus untuk dielakkan pg_read_file(). Hal yang sama juga dapat dicapai dengan tabel sementara dan COPY- mengisi hanya 1 kolom dari 1 baris.
Erwin Brandstetter
4

The pg_read_binary_fileFungsi bisa melakukan ini.

Ini memiliki keterbatasan: baru di PostgreSQL 9.1 atau lebih tinggi; harus sesi yang dimiliki oleh pengguna super basis data; harus membaca file di dalam direktori database atau di bawah ini. Itu dapat diterima dalam kasus penggunaan saya.

Jadi yang berikut ini akan berfungsi untuk membuat XMLnilai asli dari file:

-- PostgreSQL 9.1 or later.
SELECT
    XMLPARSE(DOCUMENT convert_from(
        pg_read_binary_file('foo.xml'), 'UTF8'));

Dalam PostgreSQL 8.3 - 9.0, pg_read_filefungsi tersebut dapat digunakan, dengan batasan tambahan yang Anda tidak dapat menentukan pengkodean file-spesifik (membaca file sebagai teks dalam pengkodean sesi saat ini).

-- PostgreSQL earlier than 9.1.
SELECT
    XMLPARSE(DOCUMENT pg_read_file('foo.xml'));
hidung besar
sumber
3

Saya telah memposting implementasi lengkap dari apa yang Anda minta dalam jawaban terakhir pada SO .

Fitur utama adalah xpath()fungsi,, pg_read_file()penanganan array, fungsi plpgsql, ..

Erwin Brandstetter
sumber
Agak berbeda (dan lebih berat) dari apa yang saya butuhkan dalam hal ini. Tapi +1 untuk arahan yang baik, terima kasih.
bignose
Ini bukan yang kelas berat, misalnya saya hanya sangat lengkap dengan unsur-unsur berlebihan untuk menunjukkan varian sintaks.
Erwin Brandstetter