Как мне вернуть sys_refcursor из оракула SP в Java?

У меня есть хранимая процедура (SP) в Oracle:

CREATE OR REPLACE 
PROCEDURE "SP_SEL_LOGIN_INFO" (
p_username IN varchar2,
p_ResultSet OUT sys_refcursor
) AS

begin

OPEN p_ResultSet FOR
SELECT * FROM user_accounts
WHERE p_username = username;

end;

В моем Java-классе у меня есть следующие строки кода для вызова SP:

currentCon = connectionpackage.ConnectionManager.getConnection(dbSource);
CallableStatement stmt = currentCon.prepareCall("{call SP_SEL_LOGIN_INFO(?, ?)}");
stmt.setString(1, username); 
stmt.registerOutParameter(2, OracleTypes.CURSOR); //REF CURSOR
stmt.execute();
rs = stmt.getCursor(2);

Это то, что я нашел в Интернете, чтобы вызвать SP и вернуть курсор. Когда я пытаюсь скомпилировать, я получаю две следующие ошибки:

error: cannot find symbol stmt.registerOutParameter(2, OracleTypes.CURSOR); А ТАКЖЕ error: cannot find symbol rs = stmt.getCursor(2); Где он говорит, что не может найти OracleTypes и getCursor.

Я пытался импортировать import oracle.jdbc.driver.*; или же import oracle.jdbc.*; и получил ошибки error: package oracle.jdbc does not exist import oracle.jdbc.driver.*; а также error: package oracle.jdbc does not exist import oracle.jdbc.*; соответственно.

У меня также есть файл ojdbc14.jar в соответствующей папке, и я могу подключиться с помощью строки запроса. Просто при попытке использовать SP это доставляет мне неприятности.

SP является тем, который мы используем на нашем текущем веб-сайте CF, поэтому я хотел бы просто использовать его как есть. Может ли кто-нибудь пролить свет на то, почему это может не сработать? Или, если есть альтернативный бит кода, который можно использовать для возврата курсора из Oracle SP? Благодарю.

4 ответа

Решение

Пожалуйста, попробуйте это, это может решить проблему.

Замени это

rs = stmt.getCursor(2);

с

 rs = ((OracleCallableStatement)stmt).getCursor(2);

Кроме того, для вызова вашей процедуры используйте это утверждение.

CallableStatement stmt = conn.prepareCall("BEGIN SP_SEL_LOGIN_INFO(?, ?); END;");

Вы также можете попробовать вот так:

rs = (ResultSet) stmt.getObject(2);
while (rs.next()) {
     String field1 = rs.getString(1);
     System.out.println(field1);
}

он работает правильно на моей стороне

Может ли кто-нибудь пролить свет на то, почему это может не сработать? Или, если есть альтернативный бит кода, который можно использовать для возврата курсора из Oracle SP?

Если вы хотите вернуться только resultsets(записи), то почему бы не использовать функцию, которая возвращает sys_refcursor чем хранимая процедура? Конечно, это не имеет никакого значения, если вы используете procedure или же function с точки зрения производительности, а function будет лучшей практикой, как ваш procedure не делает ничего, кроме select заявление.

С уважением

      public LoanResponse getActiveLoan(LoanOverview loanDetails) {
    LoanResponse response = new LoanResponse();
    ErrorResponse error = null;
    try {
        SimpleJdbcCall procedure = new SimpleJdbcCall(jdbc).withProcedureName("GET_ALL_LOAN_DETAILS_BY_USER")
                .returningResultSet("P_ASSET_RESULT", new LOAN_OVERVIEW_ROWMAPPER()));
        MapSqlParameterSource input = new MapSqlParameterSource().addValue("P_UUID", loanDetails.getUuid());
        Map<String, Object> result = procedure.execute(input);
        List<LoanOverview> loanDtls = (List) result.get("P_ASSET_RESULTS");
        if (!CollectionUtils.isEmpty(loanDtls) ) {
            response.setLoanOverview(loanDtls);
            error = SUCCESS_ERROR;
        } else {
            error = NODATA_ERROR;
        }
    } catch (Exception e) {
        log.error(e.getMessage());
        error = EXCEPTION_ERROR;
    }
    response.setError(error);
    return response;
}
Другие вопросы по тегам