هو استخدام DBMS_LOB الضرورة عند عودته CLOB من إجراءات PL / SQL؟

StackOverflow https://stackoverflow.com/questions/1613408

سؤال

وأود أن خلق بعض الإجراءات PL / SQL التي ترجع XML كمعلمات CLOB. أريد أن تفعل هذا (الذي يعمل بشكل جيد مع الاختبارات البسيطة):

create or replace procedure p_xml_test_1(
  p_xml out nocopy clob
) is
begin
  p_xml := '<?xml version="1.0" encoding="utf8" ?>' ||
    '<test><something>some value</something></test>';
end p_xml_test_1;

ولكن أنا من الحصول على بعض التعليمات البرمجية مصدر آخر أن الأساس يفعل هذا:

create or replace procedure p_xml_test_2(
  p_xml out nocopy clob
) is
  lv_xml clob;
begin
  dbms_lob.createtemporary(
    lob_loc => p_xml,
    cache   => true
  );

  lv_xml := '<?xml version="1.0" encoding="utf8" ?>' ||
    '<test><something>some value</something></test>';

  dbms_lob.writeappend(
    lob_loc => p_xml,
    amount  => length(lv_xml),
    buffer  => lv_xml
  );
end p_xml_test_2;

وأنا أتساءل عما إذا كانت الطريقة الأولى سوف يسبب أي مشاكل بالنسبة لي على الطريق. هل هو موافق لتفعل ذلك بهذه الطريقة؟ ما هي الميزة، إن وجدت، إلى الطريقة الثانية؟ شكرا!

هل كانت مفيدة؟

المحلول

وأعتقد أن عليك أن قياس أداء كل من الأساليب التي تشغيلها عدة مرات في حلقة. وأعتقد أن الأداء هو الفرق الوحيد. كتلة أكس الخاص بك هو القصير ولكن عند لسلسلة كتلة أكس كبير وهو أسرع لسلسلة مع dbms_low.writeappend من استخدام ||.

و(على الأقل كان في أوراكل 9، وأعتقد أن الفارق في الأداء أصغر في أوراكل 10.)

نصائح أخرى

وركضت الإجراءات التالية لمقارنة وقت التنفيذ:

صفحة 1

create or replace procedure p_xml_test_1(
  p_xml out nocopy clob
) is
  lv_i number;
begin
  for lv_i in 1 .. 999999 loop
    p_xml := p_xml || 'a';
  end loop;
end p_xml_test_1;

والإصدار 2

create or replace procedure p_xml_test_2(
  p_xml out nocopy clob
) is
  lv_xml clob;
  lv_i   number;
begin
  dbms_lob.createtemporary(
    lob_loc => p_xml,
    cache   => true
  );

  for lv_i in 1 .. 999999 loop
    lv_xml := 'a';

    dbms_lob.writeappend(
      lob_loc => p_xml,
      amount  => length(lv_xml),
      buffer  => lv_xml
    );
  end loop;
end p_xml_test_2;

والفرق هو neglible. كل من يأتي في حوالي 0.2 ثانية باستمرار.

إذا قمت بتغيير إجراءات لحلقة 999999 بدلا من 10000، نسخة الأداء 1 ليبدأ في الانخفاض إلى حد ما (حوالي 39 ثانية مقابل 32 ثانية لversion2).

وأنا لا أرى أي سبب لماذا كنت تريد استخدام ثانية واحدة.

إذا كان lv_xml على VARCHAR2 بدلا من CLOB ثم أرى سببا وجيها جدا (طول الحد الأقصى من سلسلة الحرفي مقابل طول الحد الأقصى من CLOB).

وشكرا على الأجوبة. وبناء على ما قرأته في موقع المدرجة أدناه، أنا ذاهب لنفترض أنه في الواقع شيء جيد لاستخدام dbms_lob.writeappend. إذا كنت لا، قد أكون كذلك باستخدام VARCHAR2s (التي لن تكون كبيرة بما فيه الكفاية في بعض الحالات).

<اقتباس فقرة>   

إذا كان لديك متغير CLOB يسمى "l_clob"، وأنت تفعل شيئا مثل "l_clob: = l_clob || l_some_string_to_concatenate."، فإنه سيتم تحويل قيمة l_clob على الجانب الأيمن من المعادلة لVARCHAR2 قبل القيام سلسلة وربما تعطيك نتائج غير صحيحة أو خطأ.

http://www.maristream.org/srea/Huge_Strings_Using_LOBs.htm

وهناك خيار آخر التي لا أذكر: استخدام أوراكل المدمج في وظائف XML (على افتراض لديك إصدار قاعدة بيانات 9I أو أعلى). على سبيل المثال، وتوليد وثيقة XML من استعلام هو القصاصة مع DBMS_XMLGEN.getXML() أو DBMS_XMLGEN.getXMLType().

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top