어떻게 스프링 JDBC와 Oracle 저장 프로 시저의 IN OUT 매개 변수를 사용하는 방법?

티아 가라 잔 Ramanathan :

내 저장 프로 시저, 나는 네 개의 매개 변수가 있습니다. 매개 변수 중 하나는 IN과 OUT 모두 있습니다. 및 출력과 매개 변수에 액세스하는 동안 나는 문제에 직면하고있다.

(CallableStatement로 사용) 일반적인 접근 방식에서 나는 결과를 가져올 수 있어요. (Sonarqube의 문제를 방지하기 위해 사용) CallableStatementCreatorFactory를 사용할 때이 문제에 직면하고있다. 나는 CallableStatementCreatorFactory를 사용하여 솔루션을 찾고 있어요. 내가 저장 프로 시저의 변화를 할 수 없습니다.

순서

PROCEDURE SOMENAME (
applicationname           IN     VARCHAR2,
username                  IN OUT VARCHAR2,
sessionid                 IN     VARCHAR2 DEFAULT NULL,
usertype                  OUT    VARCHAR2,

봄 부팅 코드

public static final String STORED_PROCEDURE_SOME_NAME = "{call TEST.PKG.SOMENAME(?,?,?,?)}";

CallableStatementCreatorFactory callableStatementCreatorFactory = new CallableStatementCreatorFactory(STORED_PROCEDURE_SOME_NAME);
callableStatementCreatorFactory.addParameter(new SqlParameter("APPLICATIONNAME", OracleTypes.VARCHAR));
callableStatementCreatorFactory.addParameter(new SqlParameter("USERNAME", OracleTypes.VARCHAR));
callableStatementCreatorFactory.addParameter(new SqlParameter("sessionid", OracleTypes.VARCHAR));
//callableStatementCreatorFactory.addParameter(new SqlOutParameter("USERNAME", OracleTypes.VARCHAR));  - throwing issue
callableStatementCreatorFactory.addParameter(new SqlOutParameter("usertype", OracleTypes.VARCHAR));

final Map<String, Object> param = new HashMap<>();
param.put("APPLICATIONNAME", applicationName);
param.put("USERNAME", userName);
param.put("sessionid", sessionGuid);


CallableStatementCallback<User> callableStatementCallback = new CallableStatementCallback<User>()
{
@Override
public User doInCallableStatement(CallableStatement callableStatement) throws SQLException
{
  try
  {
    callableStatement.execute();
    User userModel = new User();
    //userModel.setUserName(callableStatement.getString(2));  - throwing issue
    userModel.setUserType(callableStatement.getString(4));
    return populateUser(callableStatement);
  }
  finally
  {
    try
    {
      callableStatement.close();
    }
    catch (SQLException e)
    {
      LOGGER.error(MESSAGE_ERROR_CALLABLESTATEMENT_CLOSE, e);
    }
  }
}
};

CallableStatementCreator callableStatementCreator = callableStatementCreatorFactory.newCallableStatementCreator(param);
userModel = jdbcTemplate.execute(callableStatementCreator, callableStatementCallback);

나는 '추가를 추가 할 때? '쿼리에서, 나는 다음과 같은 예외를 얻을 :

org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback; bad SQL grammar [{call TEST.PKG.SOMENAME(?,?,?,?,?)}]; nested exception is java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'SOMENAME'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

나는 다음과 같은 문제를 얻을 다음 행의 주석을 해제 할 때 (추가 물음표를 제거)

callableStatementCreatorFactory.addParameter(new SqlOutParameter("USERNAME", OracleTypes.VARCHAR)); 

예외

org.springframework.jdbc.InvalidResultSetAccessException: CallableStatementCallback; invalid ResultSet access for SQL [{call TEST.PKG.SOMENAME(?,?,?,?)}]; nested exception is java.sql.SQLException: Invalid column index

나는 다음 행의 주석을 해제 할 때 나는 다음과 같은 오류가 발생합니다 :

userModel.setUserName(callableStatement.getString(TWO));  (after commenting previous line and removing one addtional ?)

예외

org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [{call TEST.PKG.SOMENAME(?,?,?,?)}]; SQL state [99999]; error code [17021]; Missing defines; nested exception is java.sql.SQLException: Missing defines
누가 복음 우드워드 :

귀하의 매개 변수는 것입니다 IN OUT당신이 사용해야하므로 매개 변수 SqlInOutParameter그것을 위해.

줄 바꾸기

    callableStatementCreatorFactory.addParameter(new SqlParameter("USERNAME", OracleTypes.VARCHAR));

    callableStatementCreatorFactory.addParameter(new SqlInOutParameter("USERNAME", OracleTypes.VARCHAR));

여분을 추가하지 마십시오 ?, 저장 프로 시저에 네 개의 매개 변수가 있습니다.

시도가를 만들 수있는 주석 처리 된 라인 삭제 SqlOutParameter를 들어 USERNAME. 그러나 행의 주석을 해제 할 수 있어야한다

    //userModel.setUserName(callableStatement.getString(2));  - throwing issue

당신이 다시 데이터베이스에서 얻을 사용자 이름을 읽을 줄을 사용합니다.

난 당신의 코드에 이러한 수정을 만들어 당신과 같은 서명 프로 시저를 호출하고 절차의 데이터를 다시 읽어 사용할 수 있었다.

또한, 내 가까이 문을 안 CallableStatementCallback: 나는 당신이 그것으로 마친 후 봄이 문을 다른 물건을 할 것이기 때문에이 예외가 발생 것을 발견,하지만 당신은 문을 닫은 경우이 작업을 수행 할 수 없습니다. 이 그것으로 완료하면 Spring은 문을 닫습니다. 봄이 JDBC를 어떻게 사용의 장점 중 하나는이 같은 지루한 상용구 물건을 많이 처리하는 것입니다.

추천

출처http://43.154.161.224:23101/article/api/json?id=239671&siteId=1