SQL将XML从文件读入PostgreSQL数据库


12

如何编写SQL将XML文件读入PostgreSQL XML值?

PostgreSQL具有本机XML数据类型,该XMLPARSE函数具有将文本字符串解析为该类型的功能。它还具有从文件系统读取数据的方法。在COPY声明中,等等。

但是我看不到编写本机PostgreSQL SQL语句以从文件系统条目中读取内容并使用其填充XML值的方法。我怎样才能做到这一点?

Answers:


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列。
Erwin Brandstetter

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

在SO最新答案中,我已经发布了您所要求的完整实现。

关键功能是xpath()函数,pg_read_file()数组处理,plpgsql函数..


在这种情况下,与我所需要的完全不同(并且更重)。但是+1是正确的方向,谢谢。
bignose

并不是那么繁重,我的示例只是非常完整的,有多余的元素来演示语法变体。
Erwin Brandstetter
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.