public Map<String, ?> matchInParameterValuesWithCallParameters(Object[] parameterValues) { Map<String, Object> matchedParameters = new HashMap<>(parameterValues.length); int i = 0; for (SqlParameter parameter : this.callParameters) { if (parameter.isInputValueProvided()) { String parameterName = parameter.getName(); matchedParameters.put(parameterName, parameterValues[i++]); } } return matchedParameters; }
/** * Build the parameter binding fragment. * @param parameter call parameter * @return parameter binding fragment * @since 4.2 */ protected String createParameterBinding(SqlParameter parameter) { return (isNamedBinding() ? parameter.getName() + " => ?" : "?"); }
/** * Find a matching parameter in the given list of declared parameters. * @param declaredParams the declared SqlParameter objects * @param paramName the name of the desired parameter * @param paramIndex the index of the desired parameter * @return the declared SqlParameter, or {@code null} if none found */ @Nullable private static SqlParameter findParameter( @Nullable List<SqlParameter> declaredParams, String paramName, int paramIndex) { if (declaredParams != null) { // First pass: Look for named parameter match. for (SqlParameter declaredParam : declaredParams) { if (paramName.equals(declaredParam.getName())) { return declaredParam; } } // Second pass: Look for parameter index match. if (paramIndex < declaredParams.size()) { SqlParameter declaredParam = declaredParams.get(paramIndex); // Only accept unnamed parameters for index matches. if (declaredParam.getName() == null) { return declaredParam; } } } return null; }
/** * Add a declared parameter to the list of parameters for the call. * <p>Only parameters declared as {@code SqlParameter} and {@code SqlInOutParameter} will * be used to provide input values. This is different from the {@code StoredProcedure} * class which - for backwards compatibility reasons - allows input values to be provided * for parameters declared as {@code SqlOutParameter}. * @param parameter the {@link SqlParameter} to add */ public void addDeclaredParameter(SqlParameter parameter) { Assert.notNull(parameter, "The supplied parameter must not be null"); if (!StringUtils.hasText(parameter.getName())) { throw new InvalidDataAccessApiUsageException( "You must specify a parameter name when declaring parameters for \"" + getProcedureName() + "\""); } this.declaredParameters.add(parameter); if (logger.isDebugEnabled()) { logger.debug("Added declared parameter for [" + getProcedureName() + "]: " + parameter.getName()); } }
/** * Declare a parameter. Overridden method. * Parameters declared as {@code SqlParameter} and {@code SqlInOutParameter} * will always be used to provide input values. In addition to this any parameter declared * as {@code SqlOutParameter} where an non-null input value is provided will also be used * as an input paraneter. * <b>Note: Calls to declareParameter must be made in the same order as * they appear in the database's stored procedure parameter list.</b> * Names are purely used to help mapping. * @param param parameter object */ @Override public void declareParameter(SqlParameter param) throws InvalidDataAccessApiUsageException { if (param.getName() == null) { throw new InvalidDataAccessApiUsageException("Parameters to stored procedures must have names as well as types"); } super.declareParameter(param); }
/** * Validate the named parameters passed to an execute method based on declared parameters. * Subclasses should invoke this method before every {@code executeQuery()} or * {@code update()} method. * @param parameters parameter Map supplied (may be {@code null}) * @throws InvalidDataAccessApiUsageException if the parameters are invalid */ protected void validateNamedParameters(@Nullable Map<String, ?> parameters) throws InvalidDataAccessApiUsageException { checkCompiled(); Map<String, ?> paramsToUse = (parameters != null ? parameters : Collections.<String, Object> emptyMap()); int declaredInParameters = 0; for (SqlParameter param : this.declaredParameters) { if (param.isInputValueProvided()) { if (!supportsLobParameters() && (param.getSqlType() == Types.BLOB || param.getSqlType() == Types.CLOB)) { throw new InvalidDataAccessApiUsageException( "BLOB or CLOB parameters are not allowed for this kind of operation"); } if (param.getName() != null && !paramsToUse.containsKey(param.getName())) { throw new InvalidDataAccessApiUsageException("The parameter named '" + param.getName() + "' was not among the parameters supplied: " + paramsToUse.keySet()); } declaredInParameters++; } } validateParameterCount(paramsToUse.size(), declaredInParameters); }
for (SqlParameter parameter : this.callParameters) { if (parameter.isInputValueProvided()) { String parameterName = parameter.getName(); String parameterNameToMatch = provider.parameterNameToUse(parameterName); if (parameterNameToMatch != null) {
/** * Delegate method to perform the actual call processing. */ private Map<String, Object> executeCallInternal(Map<String, ?> args) { CallableStatementCreator csc = getCallableStatementFactory().newCallableStatementCreator(args); if (logger.isDebugEnabled()) { logger.debug("The following parameters are used for call " + getCallString() + " with " + args); int i = 1; for (SqlParameter param : getCallParameters()) { logger.debug(i + ": " + param.getName() + ", SQL type "+ param.getSqlType() + ", type name " + param.getTypeName() + ", parameter class [" + param.getClass().getName() + "]"); i++; } } return getJdbcTemplate().call(csc, getCallParameters()); }
for (SqlParameter parameter : this.callParameters) { if (parameter.isInputValueProvided()) { String parameterName = parameter.getName(); String parameterNameToMatch = obtainMetaDataProvider().parameterNameToUse(parameterName); if (parameterNameToMatch != null) {
Object inValue = this.inParameters.get(declaredParam.getName()); if (declaredParam instanceof ResultSetSupportingSqlParameter) { if (!this.inParameters.containsKey(declaredParam.getName())) { throw new InvalidDataAccessApiUsageException( "Required input parameter '" + declaredParam.getName() + "' is missing");
/** * Execute the stored procedure with the provided parameter values. This is * a convenience method where the order of the passed in parameter values * must match the order that the parameters where declared in. * @param inParams variable number of input parameters. Output parameters should * not be included in this map. It is legal for values to be {@code null}, and this * will produce the correct behavior using a NULL argument to the stored procedure. * @return map of output params, keyed by name as in parameter declarations. * Output parameters will appear here, with their values after the stored procedure * has been called. */ public Map<String, Object> execute(Object... inParams) { Map<String, Object> paramsToUse = new HashMap<>(); validateParameters(inParams); int i = 0; for (SqlParameter sqlParameter : getDeclaredParameters()) { if (sqlParameter.isInputValueProvided() && i < inParams.length) { paramsToUse.put(sqlParameter.getName(), inParams[i++]); } } return getJdbcTemplate().call(newCallableStatementCreator(paramsToUse), getDeclaredParameters()); }
String paramName = param.getName(); if (paramName == null) { throw new IllegalArgumentException("Anonymous parameters not supported for calls - " +
public Map<String, ?> matchInParameterValuesWithCallParameters(Object[] parameterValues) { Map<String, Object> matchedParameters = new HashMap<String, Object>(parameterValues.length); int i = 0; for (SqlParameter parameter : this.callParameters) { if (parameter.isInputValueProvided()) { String parameterName = parameter.getName(); matchedParameters.put(parameterName, parameterValues[i++]); } } return matchedParameters; }
public void addParameter(CallableStatement callableStatement, Map batchRow) throws SQLException { int i = 1; for (SqlParameter parameter : getSqlParameterList()) { StatementCreatorUtils.setParameterValue(callableStatement, i, parameter, batchRow.get(parameter.getName())); i++; } }
/** * Add a declared parameter to the list of parameters for the call. * Only parameters declared as {@code SqlParameter} and {@code SqlInOutParameter} * will be used to provide input values. This is different from the {@code StoredProcedure} class * which for backwards compatibility reasons allows input values to be provided for parameters declared * as {@code SqlOutParameter}. * @param parameter the {@link SqlParameter} to add */ public void addDeclaredParameter(SqlParameter parameter) { Assert.notNull(parameter, "The supplied parameter must not be null"); if (!StringUtils.hasText(parameter.getName())) { throw new InvalidDataAccessApiUsageException( "You must specify a parameter name when declaring parameters for \"" + getProcedureName() + "\""); } this.declaredParameters.add(parameter); if (logger.isDebugEnabled()) { logger.debug("Added declared parameter for [" + getProcedureName() + "]: " + parameter.getName()); } }
/** * Declare a parameter. Overridden method. * Parameters declared as {@code SqlParameter} and {@code SqlInOutParameter} * will always be used to provide input values. In addition to this any parameter declared * as {@code SqlOutParameter} where an non-null input value is provided will also be used * as an input paraneter. * <b>Note: Calls to declareParameter must be made in the same order as * they appear in the database's stored procedure parameter list.</b> * Names are purely used to help mapping. * @param param parameter object */ @Override public void declareParameter(SqlParameter param) throws InvalidDataAccessApiUsageException { if (param.getName() == null) { throw new InvalidDataAccessApiUsageException("Parameters to stored procedures must have names as well as types"); } super.declareParameter(param); }
/** * Method to perform the actual call processing */ private Map<String, Object> executeCallInternal(Map<String, ?> params) { CallableStatementCreator csc = getCallableStatementFactory().newCallableStatementCreator(params); if (logger.isDebugEnabled()) { logger.debug("The following parameters are used for call " + getCallString() + " with: " + params); int i = 1; for (SqlParameter p : getCallParameters()) { logger.debug(i++ + ": " + p.getName() + " SQL Type "+ p.getSqlType() + " Type Name " + p.getTypeName() + " " + p.getClass().getName()); } } return getJdbcTemplate().call(csc, getCallParameters()); }