SQL để đọc XML từ tệp vào cơ sở dữ liệu PostgreQuery


12

Làm cách nào tôi có thể viết SQL để đọc tệp XML thành XMLgiá trị PostgreSQL ?

PostgreSQL có kiểu dữ liệu XML nguyên gốc với XMLPARSEchức năng phân tích chuỗi văn bản thành kiểu đó. Nó cũng có cách để đọc dữ liệu từ hệ thống tập tin; các COPYtuyên bố, trong số những người khác.

Nhưng tôi không thấy cách viết các câu lệnh SQL PostgreSQL gốc để đọc nội dung từ mục nhập hệ thống tệp và sử dụng nội dung đó để điền vào một XMLgiá trị. Tôi có thể làm cái này như thế nào?

Câu trả lời:


10

Tương tự như câu trả lời này cho câu hỏi trước đó và nếu bạn không muốn các hạn chếpg_read_file() (nói ngắn gọn: pg_read_filekhông thể đọc các tệp bên ngoài thư mục cơ sở dữ liệu và đọc văn bản trong mã hóa ký tự của phiên hiện tại).

Hàm này hoạt động cho bất kỳ đường dẫn nào, nhưng cần phải được tạo dưới dạng siêu người dùng:

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 đã được giới thiệu vào tháng 9 vì vậy đối với các phiên bản cũ hơn, bạn sẽ cần:

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

sau đó:

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

1
+1, cảm ơn vì đã chỉ ra rằng có các giới hạn đối với các chức năng đọc tệp.
bignose

1
+1 mẹo hay để lách pg_read_file(). Điều tương tự cũng có thể đạt được với một bảng tạm thời và COPY- chỉ điền 1 cột của 1 hàng.
Erwin Brandstetter

4

Các pg_read_binary_filechức năng có thể làm điều này.

Nó có những hạn chế: mới trong PostgreSQL 9.1 trở lên; phải là một phiên thuộc sở hữu của siêu người dùng cơ sở dữ liệu; phải đọc một tập tin trong thư mục cơ sở dữ liệu hoặc bên dưới. Những người được chấp nhận trong trường hợp sử dụng của tôi.

Vì vậy, sau đây sẽ làm việc để tạo một XMLgiá trị gốc từ một tệp:

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

Trong PostgreQuery 8.3 - 9.0, pg_read_filechức năng có thể được sử dụng, với giới hạn bổ sung là bạn không thể chỉ định mã hóa cụ thể cho tệp (nó đọc tệp dưới dạng văn bản trong mã hóa của phiên hiện tại).

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

3

Tôi đã đăng một triển khai đầy đủ những gì bạn đang yêu cầu trong một câu trả lời gần đây trên SO .

Các tính năng chính là xpath()chức năng, pg_read_file()xử lý mảng, chức năng plpgsql, ..


Khá khác biệt (và nặng hơn) so với những gì tôi cần trong trường hợp này. Nhưng +1 cho hướng tốt, cảm ơn bạn.
bignose

Nó không quá nặng nề, ví dụ của tôi chỉ là rất đầy đủ với các yếu tố dư thừa để thể hiện các biến thể cú pháp.
Erwin Brandstetter
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.