SQL для читання XML з файлу в базу даних PostgreSQL


12

Як я можу написати SQL, щоб прочитати XML-файл у XMLзначення PostgreSQL ?

PostgreSQL має вбудований тип даних XML з XMLPARSEфункцією розбору текстового рядка до цього типу. Він також має способи зчитування даних з файлової системи; COPYзаяву, серед інших.

Але я не бачу способу писати нативні висловлювання PostgreSQL SQL, щоб прочитати вміст із запису файлової системи та використовувати його для заповнення XMLзначення. Як я можу це зробити?

Відповіді:


10

Подібно до цієї відповіді на попереднє запитання, і якщо ви не хочете, щоб обмеженняpg_read_file() (коротше кажучи: pg_read_fileне може читати файли за межами каталогу бази даних та читає текст у кодуванні символів поточного сеансу).

Ця функція працює для будь-якого шляху, але її потрібно створити як суперпользователь:

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 було введено в 9.4, тож для старих версій вам знадобиться:

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;$$;

потім:

select convert_from(stack.bytea_import('/tmp/test.xml'), 'utf8')::xml;

1
+1, дякую за те, що вказали, що функції читання файлів є обмеженими.
bignose

1
+1 приємна хитрість обійти pg_read_file(). Те ж саме можна досягти і з тимчасовою таблицею і COPY- заповнити лише 1 стовпчик з 1 ряду.
Ервін Брандстеттер

4

pg_read_binary_fileФункція може зробити це.

Він має обмеження: нові в PostgreSQL 9.1 або вище; повинен бути сеансом, що належить користувачеві бази даних; повинен прочитати файл у каталозі бази даних або нижче. Це прийнятні в моєму випадку використання.

Отже, для створення нативного XMLзначення з файлу буде працювати наступне :

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

У PostgreSQL 8.3 - 9.0 pg_read_fileфункцію можна використовувати, з додатковим обмеженням, що ви не можете вказати специфічне для файлу кодування (воно читає файл як текст у кодуванні поточного сеансу).

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

3

Я опублікував повну реалізацію того, що ви просите, в нещодавній відповіді на ТА .

Ключові особливості - це xpath()функція, pg_read_file()обробка масиву, функції plpgsql, ..


Швидше інший (і більш важкий), ніж те, що мені потрібно в цьому випадку. Але +1 за хороший напрямок, дякую.
bignose

Це не така важка вага, мій приклад просто дуже повний із зайвими елементами, щоб продемонструвати варіанти синтаксису.
Erwin Brandstetter
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.