/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jdbi.v3.core.statement;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import org.jdbi.v3.core.Handle;
import org.jdbi.v3.core.argument.Argument;

Used for invoking stored procedures.
/** * Used for invoking stored procedures. */
public class Call extends SqlStatement<Call> { private final List<OutParamArgument> params = new ArrayList<>(); public Call(Handle handle, String sql) { super(handle, sql); }
Register a positional output parameter
Params:
  • position – the parameter position (zero-based)
  • sqlType – an SQL type constant as defined by Types or by the JDBC vendor.
Returns:self
/** * Register a positional output parameter * @param position the parameter position (zero-based) * @param sqlType an SQL type constant as defined by {@link java.sql.Types} or by the JDBC vendor. * @return self */
public Call registerOutParameter(int position, int sqlType) { return registerOutParameter(position, sqlType, null); }
Register a positional output parameter
Params:
  • position – the parameter position (zero-based)
  • sqlType – an SQL type constant as defined by Types or by the JDBC vendor.
  • mapper – a mapper which converts the CallableStatement to a desired output type.
Returns:self
/** * Register a positional output parameter * @param position the parameter position (zero-based) * @param sqlType an SQL type constant as defined by {@link java.sql.Types} or by the JDBC vendor. * @param mapper a mapper which converts the {@link CallableStatement} to a desired output type. * @return self */
public Call registerOutParameter(int position, int sqlType, CallableStatementMapper mapper) { getBinding().addPositional(position, new OutParamArgument(sqlType, mapper, null)); return this; }
Register a named output parameter
Params:
  • name – the parameter name
  • sqlType – an SQL type constant as defined by Types or by the JDBC vendor.
Returns:self
/** * Register a named output parameter * @param name the parameter name * @param sqlType an SQL type constant as defined by {@link java.sql.Types} or by the JDBC vendor. * @return self */
public Call registerOutParameter(String name, int sqlType) { return registerOutParameter(name, sqlType, null); }
Register a named output parameter
Params:
  • name – the parameter name
  • sqlType – an SQL type constant as defined by Types or by the JDBC vendor.
  • mapper – a mapper which converts the CallableStatement to a desired output type.
Returns:self
/** * Register a named output parameter * @param name the parameter name * @param sqlType an SQL type constant as defined by {@link java.sql.Types} or by the JDBC vendor. * @param mapper a mapper which converts the {@link CallableStatement} to a desired output type. * @return self */
public Call registerOutParameter(String name, int sqlType, CallableStatementMapper mapper) { getBinding().addNamed(name, new OutParamArgument(sqlType, mapper, name)); return this; }
Invoke the callable statement
Returns:the output parameters resulting from the invocation.
/** * Invoke the callable statement * @return the output parameters resulting from the invocation. */
public OutParameters invoke() { try { final PreparedStatement stmt = this.internalExecute(); OutParameters out = new OutParameters(); for (OutParamArgument param : params) { Object obj = param.map((CallableStatement) stmt); // convert from JDBC 1-based position to Jdbi's 0-based int index = param.position - 1; out.getMap().put(index, obj); if (param.name != null) { out.getMap().put(param.name, obj); } } return out; } finally { close(); } } // TODO tostring? private class OutParamArgument implements Argument { private final int sqlType; private final CallableStatementMapper mapper; private final String name; private int position; OutParamArgument(int sqlType, CallableStatementMapper mapper, String name) { this.sqlType = sqlType; this.mapper = mapper; this.name = name; params.add(this); } @Override public void apply(int position, PreparedStatement statement, StatementContext ctx) throws SQLException { ((CallableStatement) statement).registerOutParameter(position, sqlType); this.position = position; } public Object map(CallableStatement stmt) { try { if (mapper != null) { return mapper.map(position, stmt); } switch (sqlType) { case Types.CLOB: case Types.VARCHAR: case Types.LONGNVARCHAR: case Types.LONGVARCHAR: case Types.NCLOB: case Types.NVARCHAR: return stmt.getString(position); case Types.BLOB: case Types.VARBINARY: return stmt.getBytes(position); case Types.SMALLINT: return stmt.getShort(position); case Types.INTEGER: return stmt.getInt(position); case Types.BIGINT: return stmt.getLong(position); case Types.TIMESTAMP: case Types.TIME: return stmt.getTimestamp(position); case Types.DATE: return stmt.getDate(position); case Types.FLOAT: return stmt.getFloat(position); case Types.DECIMAL: case Types.DOUBLE: return stmt.getDouble(position); default: return stmt.getObject(position); } } catch (SQLException e) { throw new UnableToExecuteStatementException("Could not get OUT parameter from statement", e, getContext()); } } } }