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

big*_*ose 12 postgresql xml

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

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

但我没有看到编写原生 PostgreSQL SQL 语句来读取文件系统条目中的内容并使用它来填充XML值的方法。我怎样才能做到这一点?

Jac*_*las 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;$$;
Run Code Online (Sandbox Code Playgroud)

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;$$;
Run Code Online (Sandbox Code Playgroud)

然后:

select convert_from(stack.bytea_import('/tmp/test.xml'), 'utf8')::xml;
Run Code Online (Sandbox Code Playgroud)


big*_*ose 4

pg_read_binary_file函数可以做到这一点。

\n\n

它有局限性:PostgreSQL 9.1 或更高版本中新增;必须是数据库超级用户拥有的会话;必须读取数据库目录或以下目录中的文件。这些在我的用例中是可以接受的。

\n\n

XML因此,以下内容将用于从文件创建本机值:

\n\n
-- PostgreSQL 9.1 or later.\nSELECT\n    XMLPARSE(DOCUMENT convert_from(\n        pg_read_binary_file(\'foo.xml\'), \'UTF8\'));\n
Run Code Online (Sandbox Code Playgroud)\n\n

在 PostgreSQL 8.3 \xe2\x80\x93 9.0 中,pg_read_file可以使用该函数,但有一个额外的限制,即您不能指定特定于文件的编码(它以当前会话的编码将文件读取为文本)。

\n\n
-- PostgreSQL earlier than 9.1.\nSELECT\n    XMLPARSE(DOCUMENT pg_read_file(\'foo.xml\'));\n
Run Code Online (Sandbox Code Playgroud)\n