매개 변수 SYS_REFCURSOR
로 취하는 PL / SQL 프로 시저를 호출하는 방법을 이해하려고합니다 IN
.
다음 PL / SQL 절차를 고려하십시오.
print_cursor_contents(myCursor SYS_REFCURSOR , row_count OUT NUMBER);
IN 매개 변수에 값을 바인딩 할 때 어떤 setXXX
방법을 사용합니까?
나에게 개별 커서 레코드 필드가있는 Java 클래스는 구성원 과이 클래스의 인스턴스 배열이 plsql CURSOR를 나타내는 적절한 방법으로 보입니다. 이렇게하면 SQLException이 발생합니다.
다음 설정 방법을 사용했습니다.
callStmt.setObject(1, curRec);
위의 문을 사용하여 얻은 예외는 다음과 같습니다.
Exception occured in the database
Exception message: Invalid column type
java.sql.SQLException: Invalid column type
at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:8921)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8396)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:9176)
at oracle.jdbc.driver.OracleCallableStatement.setObject(OracleCallableStatement.java:5024)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:234)
at com.rolta.HrManager.printMaxSalAllDept(HrManager.java:1022)
at com.rolta.HrManager.main(HrManager.java:1116)
Database error code: 17004
나에게 개별 커서 레코드 필드가있는 Java 클래스는 구성원 과이 클래스의 인스턴스 배열이 plsql CURSOR를 나타내는 적절한 방법으로 보입니다.
동의하지 않습니다.
참조 커서를 반환하거나 OUT
매개 변수 로 참조 커서가있는 저장 함수 또는 프로 시저가있는 경우 참조 커서는 JDBC에서 ResultSet
. 따라서 SYS_REFCURSOR
매개 변수를 사용 하여 저장 프로 시저를 호출 ResultSet
할 수 있다면 a 가 전달해야 할 것이라고 생각합니다.
사실, 내 의심이 확인되었습니다. 당신이 오라클의 확장을 살펴하면 CallableStatement
, OracleCallableStatement
, 그것은 상속 setCursor(int, ResultSet)
을 그 슈퍼에서 방법을 OraclePreparedStatement
. 따라서 캐스팅 수 CallableStatement
에 OracleCallableStatement
호출 setCursor
방법을, 멀리 당신은 간다.
이 접근 방식은 실제로 작동하지 않는 것을 제외하고는.
당신이 호출하려고하면 setCursor
온 OracleCallableStatement
, 당신은 예외를 얻을 것이다 java.sql.SQLException: Unsupported feature
.
을 setObject
사용하여 호출 을 시도 할 수 ResultSet
있지만 다른 java.sql.SQLException: Invalid column type
예외 만 발생합니다.
다음은 두 경우 중 하나를 확인하기 위해 실행할 수있는 테스트 클래스입니다. 하나의 저장 프로 시저를 호출하여 참조 커서 (및 따라서 a ResultSet
) 를 얻은 다음이를 다른 저장 프로 시저 로 전달하려고합니다.
import java.sql.*;
import oracle.jdbc.OracleTypes;
import oracle.jdbc.OracleCallableStatement;
public class JavaRefCursorTest {
public static void main(String[] args) throws Exception {
Connection conn = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:XE", "user", "password");
try (CallableStatement cstmt1 = conn.prepareCall(
"{ call java_ref_curs_test.get_ref_cursor(?)}")) {
cstmt1.registerOutParameter(1, OracleTypes.CURSOR);
cstmt1.execute();
try (ResultSet rSet = (ResultSet)cstmt1.getObject(1)) {
try (CallableStatement cstmt2 = conn.prepareCall(
"{ call java_ref_curs_test.print_refcursor(?)}")) {
// Uncomment the next line to call setCursor:
// ((OracleCallableStatement)cstmt2).setCursor(1, rSet);
// Uncomment the next line to call setObject:
// cstmt2.setObject(1, rSet);
cstmt2.execute();
}
}
}
}
}
(취기의 두 프로시 저는 java_ref_curs_test
단일 SYS_REFCURSOR
매개 변수를 사용 get_ref_cursor
합니다. 참조 커서를 반환하고 print_refcursor
하나를 매개 변수로 사용하지만 아무것도 수행하지 않습니다.)
그렇다면 어떤 setXXX
방법을 사용해야합니까? 나는 그들 중 누구도 말하지 않을 것입니다. 당신이 요구하는 것은 직접적으로 불가능합니다.
여전히이 프로 시저를 호출 할 수는 있지만 Java가 아닌 PL / SQL에서 ref 커서를 생성 한 다음이를 프로 시저에 전달해야합니다.
예를 들어, 다음 PL / SQL 블록을 사용하여 위의 예에서 사용 된 두 가지 프로 시저를 호출 할 수 있습니다.
DECLARE
l_curs SYS_REFCURSOR;
BEGIN
java_ref_curs_test.get_ref_cursor(l_curs);
java_ref_curs_test.print_refcursor(l_curs);
END;
JDBC에서 쉽게 실행할 수 있습니다. 문자열에 넣고 Statement.executeUpdate()
.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다