it-swarm.asia

SQL لقراءة XML من ملف إلى قاعدة بيانات PostgreSQL

كيف يمكنني كتابة SQL لقراءة ملف XML في قيمة PostgreSQL XML؟

تحتوي PostgreSQL على نوع بيانات XML = مع وظيفة XMLPARSE لتحليل سلسلة نصية إلى هذا النوع. لديها أيضًا طرق لقراءة البيانات من نظام الملفات ؛ العبارة COPY ، من بين أمور أخرى.

لكنني لا أرى طريقة لكتابة عبارات PostgreSQL SQL الأصلية لقراءة المحتوى من إدخال نظام الملفات واستخدام ذلك لملء قيمة XML. كيف يمكنني أن أفعل هذا؟

12
bignose

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'));
4
bignose

يشبه هذا إجابة على سؤال سابق ، وإذا كنت لا تريد قيود 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;
10
Jack says try topanswers.xyz

لقد قمت بنشر تطبيق كامل لما تطلبه في إجابة حديثة على SO .

السمات الرئيسية هي الوظيفة xpath() الوظيفة ، pg_read_file() ، معالجة المصفوفة ، الدالات plpgsql ، ..

3
Erwin Brandstetter