मैंने यहां इस मुद्दे के बारे में ब्लॉग भी किया है। यहां एक स्निपेट दिया गया है जो बताता है कि यह कैसे किया जा सकता है:
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/