Luk*_*der 20
我也在这里写了关于这个问题的博客.这是一个片段,说明了如何做到这一点:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
以上将打印:
[abc, hello, so cool, null]
Run Code Online (Sandbox Code Playgroud)
请注意,ENABLE
/ DISABLE
setting是一个连接范围设置,因此您也可以通过多个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;");
}
}
Run Code Online (Sandbox Code Playgroud)
另请注意,这将最多获取1000行的固定大小.如果需要更多行,可能需要循环PL/SQL或轮询数据库.
DBMS_OUTPUT.GET_LINE
,而不是以前,有一个现在删除的答案,建议单独调用DBMS_OUTPUT.GET_LINE
,一次返回一行.我对比较它的方法进行了基准测试DBMS_OUTPUT.GET_LINES
,并且差异非常大 - 从JDBC调用时,速度降低了30倍(即使从PL/SQL调用过程时没有太大的区别).
因此,使用批量数据传输方法DBMS_OUTPUT.GET_LINES
绝对值得.这是基准的链接:
https://blog.jooq.org/2017/12/18/the-cost-of-jdbc-server-roundtrips/
归档时间: |
|
查看次数: |
4356 次 |
最近记录: |