SQL อ่าน XML จากไฟล์ลงในฐานข้อมูล PostgreSQL


12

ฉันจะเขียน SQL เพื่ออ่านไฟล์ XML ลงในXMLค่าPostgreSQL ได้อย่างไร

PostgreSQL มีประเภทข้อมูล XMLดั้งเดิมพร้อมXMLPARSEฟังก์ชันแยกวิเคราะห์สตริงข้อความให้เป็นประเภทนั้น นอกจากนี้ยังมีวิธีการอ่านข้อมูลจากระบบไฟล์ COPYคำสั่งอื่น ๆ ในกลุ่ม

แต่ฉันไม่เห็นวิธีการเขียนคำสั่ง PostgreSQL SQL ดั้งเดิมเพื่ออ่านเนื้อหาจากรายการระบบไฟล์และใช้เพื่อเติมXMLค่า ฉันจะทำสิ่งนี้ได้อย่างไร

คำตอบ:


10

คล้ายกับนี้คำตอบคำถามก่อนหน้านี้และถ้าคุณไม่ต้องการข้อ จำกัด ของpg_read_file() (ในระยะสั้น: pg_read_fileไม่สามารถอ่านไฟล์นอกไดเรกทอรีฐานข้อมูลและอ่านข้อความในการเข้ารหัสอักขระเซสชั่นปัจจุบัน)

ฟังก์ชั่นนี้ใช้ได้กับทุกเส้นทาง แต่ต้องสร้างเป็น 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 เปิดตัวใน 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 ขึ้นไป ต้องเป็นเซสชันของฐานข้อมูล superuser ต้องอ่านไฟล์ในไดเรกทอรีฐานข้อมูลหรือด้านล่าง สิ่งเหล่านี้เป็นที่ยอมรับในกรณีการใช้งานของฉัน

ดังนั้นต่อไปนี้จะทำงานเพื่อสร้าง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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.