Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

JDBC का उपयोग करके dbms_output.get_lines से आउटपुट प्राप्त करना

मैंने यहां इस मुद्दे के बारे में ब्लॉग भी किया है। यहां एक स्निपेट दिया गया है जो बताता है कि यह कैसे किया जा सकता है:

try (CallableStatement call = c.prepareCall(
    "declare "
  + "  num integer := 1000;" // Adapt this as needed
  + "begin "

  // You have to enable buffering any server output that you may want to fetch
  + "  dbms_output.enable();"

  // This might as well be a call to third-party stored procedures, etc., whose
  // output you want to capture
  + "  dbms_output.put_line('abc');"
  + "  dbms_output.put_line('hello');"
  + "  dbms_output.put_line('so cool');"

  // This is again your call here to capture the output up until now.
  // The below fetching the PL/SQL TABLE type into a SQL cursor works with Oracle 12c.
  // In an 11g version, you'd need an auxiliary SQL TABLE type
  + "  dbms_output.get_lines(?, num);"

  // Don't forget this or the buffer will overflow eventually
  + "  dbms_output.disable();"
  + "end;"
)) {
    call.registerOutParameter(1, Types.ARRAY, "DBMSOUTPUT_LINESARRAY");
    call.execute();

    Array array = null;
    try {
        array = call.getArray(1);
        System.out.println(Arrays.asList((Object[]) array.getArray()));
    }
    finally {
        if (array != null)
            array.free();
    }
}

ऊपर प्रिंट होगा:

[abc, hello, so cool, null]

ध्यान दें कि ENABLE / DISABLE सेटिंग एक कनेक्शन वाइड सेटिंग है, इसलिए आप इसे कई JDBC स्टेटमेंट पर भी कर सकते हैं:

try (Connection c = DriverManager.getConnection(url, properties);
     Statement s = c.createStatement()) {

    try {
        s.executeUpdate("begin dbms_output.enable(); end;");
        s.executeUpdate("begin dbms_output.put_line('abc'); end;");
        s.executeUpdate("begin dbms_output.put_line('hello'); end;");
        s.executeUpdate("begin dbms_output.put_line('so cool'); end;");

        try (CallableStatement call = c.prepareCall(
            "declare "
          + "  num integer := 1000;"
          + "begin "
          + "  dbms_output.get_lines(?, num);"
          + "end;"
        )) {
            call.registerOutParameter(1, Types.ARRAY, "DBMSOUTPUT_LINESARRAY");
            call.execute();

            Array array = null;
            try {
                array = call.getArray(1);
                System.out.println(Arrays.asList((Object[]) array.getArray()));
            }
            finally {
                if (array != null)
                    array.free();
            }
        }
    }
    finally {
        s.executeUpdate("begin dbms_output.disable(); end;");
    }
}

यह भी ध्यान दें कि यह अधिकतम 1000 लाइनों का एक निश्चित आकार प्राप्त करेगा। यदि आप और लाइनें चाहते हैं तो आपको पीएल/एसक्यूएल में लूप करने या डेटाबेस को मतदान करने की आवश्यकता हो सकती है।

कॉल करने पर एक नोट DBMS_OUTPUT.GET_LINE इसके बजाय

पहले, एक अब-हटाया गया उत्तर था जो DBMS_OUTPUT.GET_LINE पर अलग-अलग कॉल करने का सुझाव देता था। इसके बजाय, जो एक बार में एक लाइन लौटाता है। मैंने दृष्टिकोण की तुलना DBMS_OUTPUT.GET_LINES . से की है , और अंतर बहुत अधिक हैं - जब JDBC से कॉल किया जाता है तो एक कारक 30x धीमा होता है (भले ही PL/SQL से प्रक्रियाओं को कॉल करते समय वास्तव में कोई बड़ा अंतर न हो)।

इसलिए, DBMS_OUTPUT.GET_LINES . का उपयोग करके बल्क डेटा ट्रांसफर करने का तरीका निश्चित रूप से इसके लायक है। यहां बेंचमार्क का लिंक दिया गया है:

https://blog.jooq.org/2017/12/18/the-cost-of-jdbc-server-roundtrips/




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle में 10 मिनट के भीतर 10 मिलियन प्रश्नों का INSERT?

  2. संग्रहीत प्रक्रिया में वापसी का उपयोग करना संभव है?

  3. एफएनडीसीपास और AFPASSWD

  4. Oracle में किसी संख्या के लिए डिफ़ॉल्ट प्रेसिजन और स्केल क्या है?

  5. Oracle डेटाबेस में FORALL स्टेटमेंट का परिचय