이 문제를 해결하는 데 너무 가깝지만 분명히 누락되었습니다. 내 요구 사항은 JDBC에서 오라클의 저장 프로 시저를 호출하는 것입니다. 저장 프로시 듀어는 사용자 정의 Oracle 오브젝트 1 개를 INput으로, 또 다른 사용자 정의 Oracle 오브젝트를 OUTput으로 취합니다. INput 및 OUTput 객체는 원시 Oracle 데이터 유형과 다른 사용자 정의 객체 집합의 컬렉션을 혼합합니다. 나는 성공적으로 저장 프로 시저를 호출하고 INput 및 OUTput 객체의 콜렉션 유형에 NULL을 설정하는 한 결과를 다시 얻을 수있다. 오라클 객체 목록에 ArrayDescriptor를 만들어 저장 프로 시저에 보내려고하면로드 블록이 계속 발생합니다. 그래서 Array를 INput 객체로 설정하고 CallableStatement로 설정하는 방법에 대한 도움이 필요합니다. 저장 프로 시저에 직접 입력으로 원시 형식 및 배열을 보낼 수있는 방법을 알고 있습니다. 그러나 우리가 나중에 절차에 10 개의 추가 필드를 보내야하기 때문에 그렇게하지 않으려 고합니다. 메소드 서명에 추가하지 않으려합니다. 다음은 클래스 목록입니다. 또한 아래 코드에는 컴파일 오류가 없습니다. 오라클의복잡한 입력 및 출력 유형을 가진 JDBC에서 Oracle 저장 프로 시저를 호출하십시오.
패키지 :
create or replace TYPE ARR_OBJ_1_NT AS TABLE OF ARR_OBJ_1_OBJ;
: 입력 개체의 일환으로
CREATE OR REPLACE TYPE TESTDATA_IN_OBJ AS OBJECT(
testStr1 VARCHAR2(5),
arrObj1 ARR_OBJ_1_NT);
배열 개체 : 저장 프로 시저에 대한
CREATE OR REPLACE PACKAGE testPkg AS
PROCEDURE spGetTestData (
TESTDATA_IN IN TESTDATA_IN_OBJ,
TESTDATA_OUT OUT TESTDATA_OUT_OBJ
);
END;
입력 객체 입력 개체의 17,451,515,
사용자 정의 된 개체 부분 :
CREATE OR REPLACE TYPE ARR_OBJ_1_OBJ AS OBJECT
(
teststr VARCHAR2(14),
testNumber NUMBER(4),
);
TestDataINObj.java :
import java.sql.Array;
import java.sql.SQLData;
import java.sql.SQLException;
import java.sql.SQLInput;
import java.sql.SQLOutput;
public class TestDataINObj implements SQLData
{
private String sql_type = "TESTDATA_IN_OBJ";
protected String testStr1;
protected Array arrObj1;
@Override
public String getSQLTypeName() throws SQLException
{
return this.sql_type;
}
// getter and setter for fields
@Override
public void readSQL(SQLInput stream, String typeName) throws SQLException
{
this.sql_type=typeName;
this.testStr1 = stream.readString();
this.arrObj1 = stream.readArray();
}
@Override
public void writeSQL(SQLOutput stream) throws SQLException
{
stream.writeString(this.testStr1);
stream.writeArray(this.arrObj1);
}
}
TestDataINObjConverter.java :
public class TestDataINObjConverter
{
public static TestDataINObj convertPOJOToDBInObj(Connection connection)
throws SQLException
{
TestDataINObj testDataINObj = new TestDataINObj();
testDataINObj.setTestStr1("some string");
ArrObj1NT[] ArrObj1NTList = ArrObj1NTConverter.convertPOJOToDBObj(); // this will return Java array of ArrObj1NT class
testDataINObj.setArrObj1(getOracleArray("ARR_OBJ_1_NT",connection, ArrObj1NTList));
return testDataINObj;
}
private static Array getOracleArray(final String typeName, Connection connection, ArrObj1NT[] ArrObj1NTList) throws SQLException
{
if (typeName == null)
{
return null;
}
Array oracleArray = new ARRAY(new ArrayDescriptor(typeName, connection), connection, ArrObj1NTList);
return oracleArray;
}
코드
기타... //code to get connection
..// connection is of type T4CConnection
Map typeMap = connection.getTypeMap();
typeMap.put("TESTDATA_IN_OBJ", TestDataINObj.class);
typeMap.put("TESTDATA_OUT_OBJ", TestDataOUTObj.class);
typeMap.put("ARR_OBJ_1_NT", ArrObj1NT.class);
TestDataINObj testDataINObj = TestDataINObjConverter.convertPOJOToDBInObj(connection);
getMetaDataCallableStatement = connection.prepareCall("begin " + "testPkg" + ".spGetTestData (?,?);"+ " end;");
getMetaDataCallableStatement.setObject(1, testDataINObj);
getMetaDataCallableStatement.registerOutParameter(2, Types.STRUCT, "TESTDATA_OUT_OBJ");
rs = getMetaDataCallableStatement.executeQuery();
TestDataOUTObj testDataOUTObj = (TestDataOUTObj) getMetaDataCallableStatement.getObject(2, typeMap);
: 1. 객체 스키마 수준에서 선언하고 DB를 사용자가 액세스하는 데 사용할 수 있습니다 그것은 실제로 저장 프로 시저에 호출을 실행합니다. 2. 더 많은 공간이 필요하므로 여기에 해당 Java 객체를 모두 포함하지 않았습니다. SQLData 인터페이스를 구현하고 유형 이름이 DB 이름과 일치합니다. read 및 writeSQL 메소드는 getString, getArray 및 해당 setter 메소드를 사용합니다.
당신은 올바른 길을 향하고 있습니다. 당신이 받고있는 예외를 게시 할 수 있습니까? – Nick
TESTDATA_OUT_OBJ 선언은 어디에 있습니까? – Nagh
이봐,이 대답을 얻었 니? –