JDBC를 사용하여 dbms_output.get_lines에서 출력 가져오기
오라클 제품에서 출력을 얻을 수 있는 방법dbms_output.get_lines
데이터베이스에 추가 개체를 만들지 않고 JDBC를 사용하는 Java 앱에서?
저는 이 문제에 대해서도 블로그에 올렸습니다.다음은 이 작업을 수행하는 방법을 보여주는 코드 조각입니다.
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줄의 고정 크기를 가져올 수 있습니다.줄을 더 늘리려면 PL/SQL에서 루프하거나 데이터베이스를 폴링해야 할 수 있습니다.
jOOQ를 사용하여 이 작업 수행
jOOQ 사용자인 경우 쿼리에서 서버 출력을 자동으로 가져올 수 있습니다.
DSLContext ctx = DSL.using(c,
new Settings().withFetchServerOutputSize(10));
그리고 나서 당신은 몇 개를 봐야 합니다.DEBUG
로그 출력FetchServerOutputListener
,예.
DEBUG [LoggerListener ] Executing query : begin my_procedure(1, 2); end;
DEBUG [FetchServerOutputListener] <output here>
상기 이외에도DEBUG
로그, 당신은 정보를 얻을 것입니다.
호출에 대한 메모DBMS_OUTPUT.GET_LINE
대신
이전에, 지금 삭제된 답변이 있었는데, 이 답변은 다음과 같은 개별 전화를 제안합니다.DBMS_OUTPUT.GET_LINE
대신 한 번에 한 줄씩 반환합니다.저는 그것을 비교하는 접근 방식을 벤치마킹했습니다.DBMS_OUTPUT.GET_LINES
그리고 그 차이는 급격합니다 - JDBC에서 호출될 때 최대 30배 더 느립니다(PL/SQL에서 프로시저를 호출할 때 큰 차이가 없는 경우에도).
따라서, 대량 데이터 전송 접근 방식은 다음과 같습니다.DBMS_OUTPUT.GET_LINES
그럴만한 가치가 있어요벤치마크 링크는 다음과 같습니다.
https://blog.jooq.org/the-cost-of-jdbc-server-roundtrips/
언급URL : https://stackoverflow.com/questions/47830370/getting-output-from-dbms-output-get-lines-using-jdbc
'programing' 카테고리의 다른 글
확인하지 못했습니다. com.google.파이어베이스:파이어베이스 코어:9.0.0 (0) | 2023.06.19 |
---|---|
SQL insert 문에서 비트 값을 반전하는 우아한 방법이 있습니까? (0) | 2023.06.19 |
파이썬의 사전 목록에 값이 이미 있는지 확인하시겠습니까? (0) | 2023.06.19 |
두 날짜 사이의 근무일만 계산하는 방법은 무엇입니까? (0) | 2023.06.19 |
C# 드라이버를 사용하여 MongoDB에 컬렉션이 있는지 확인하는 방법은 무엇입니까? (0) | 2023.06.19 |