Support for SQL Server named parameter binding (aligned with Sybase)

Closes gh-26072
See gh-30231
This commit is contained in:
Juergen Hoeller 2023-12-08 16:38:43 +01:00
parent 748dd94dab
commit afc1f37616
5 changed files with 38 additions and 33 deletions

View File

@ -678,7 +678,7 @@ public class CallMetaDataContext {
protected String createParameterBinding(SqlParameter parameter) {
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
return (isNamedBinding() ? this.metaDataProvider.namedParamBindingToUse(parameter.getName()) : "?");
return (isNamedBinding() ? this.metaDataProvider.namedParameterBindingToUse(parameter.getName()) : "?");
}
private static String lowerCase(@Nullable String paramName) {

View File

@ -30,6 +30,8 @@ import org.springframework.lang.Nullable;
* {@link org.springframework.jdbc.core.simple.SimpleJdbcCall}.
*
* @author Thomas Risberg
* @author Juergen Hoeller
* @author Giuseppe Milicia
* @since 2.5
*/
public interface CallMetaDataProvider {
@ -55,6 +57,12 @@ public interface CallMetaDataProvider {
void initializeWithProcedureColumnMetaData(DatabaseMetaData databaseMetaData, @Nullable String catalogName,
@Nullable String schemaName, @Nullable String procedureName) throws SQLException;
/**
* Get the call parameter meta-data that is currently used.
* @return a List of {@link CallParameterMetaData}
*/
List<CallParameterMetaData> getCallParameterMetaData();
/**
* Provide any modification of the procedure name passed in to match the meta-data currently used.
* <p>This could include altering the case.
@ -100,6 +108,14 @@ public interface CallMetaDataProvider {
@Nullable
String parameterNameToUse(@Nullable String parameterName);
/**
* Return the name of the named parameter to use for binding the given parameter name.
* @param parameterName the name of the parameter to bind
* @return the name of the named parameter to use for binding the given parameter name
* @since 6.1.2
*/
String namedParameterBindingToUse(@Nullable String parameterName);
/**
* Create a default out parameter based on the provided meta-data.
* <p>This is used when no explicit parameter declaration has been made.
@ -164,12 +180,6 @@ public interface CallMetaDataProvider {
*/
boolean byPassReturnParameter(String parameterName);
/**
* Get the call parameter meta-data that is currently used.
* @return a List of {@link CallParameterMetaData}
*/
List<CallParameterMetaData> getCallParameterMetaData();
/**
* Does the database support the use of catalog name in procedure calls?
*/
@ -180,11 +190,4 @@ public interface CallMetaDataProvider {
*/
boolean isSupportsSchemasInProcedureCalls();
/**
* Returns the name of the named parameter to use for binding the given parameter name.
* @param paramName the name of the parameter to bind
* @return the name of the named parameter to use for binding the given parameter name,
*/
String namedParamBindingToUse(@Nullable String paramName);
}

View File

@ -171,8 +171,8 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider {
}
@Override
public boolean byPassReturnParameter(String parameterName) {
return false;
public String namedParameterBindingToUse(@Nullable String parameterName) {
return parameterName + " => ?";
}
@Override
@ -215,6 +215,11 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider {
return this.procedureColumnMetaDataUsed;
}
@Override
public boolean byPassReturnParameter(String parameterName) {
return false;
}
/**
* Specify whether the database supports the use of catalog name in procedure calls.
@ -246,16 +251,6 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider {
return this.supportsSchemasInProcedureCalls;
}
/**
* Returns the name of the named parameter to use for binding the given parameter name.
* @param paramName the name of the parameter to bind
* @return the name of the named parameter to use for binding the given parameter name,
*/
@Override
public String namedParamBindingToUse(@Nullable String paramName) {
return paramName + " => ?";
}
/**
* Specify whether the database uses upper case for identifiers.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,6 +26,7 @@ import org.springframework.lang.Nullable;
* This class is intended for internal use by the Simple JDBC classes.
*
* @author Thomas Risberg
* @author Juergen Hoeller
* @since 2.5
*/
public class SqlServerCallMetaDataProvider extends GenericCallMetaDataProvider {
@ -54,6 +55,11 @@ public class SqlServerCallMetaDataProvider extends GenericCallMetaDataProvider {
}
}
@Override
public String namedParameterBindingToUse(@Nullable String parameterName) {
return parameterName + " = ?";
}
@Override
public boolean byPassReturnParameter(String parameterName) {
return RETURN_VALUE_NAME.equals(parameterName);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,6 +26,7 @@ import org.springframework.lang.Nullable;
* This class is intended for internal use by the Simple JDBC classes.
*
* @author Thomas Risberg
* @author Giuseppe Milicia
* @since 2.5
*/
public class SybaseCallMetaDataProvider extends GenericCallMetaDataProvider {
@ -54,15 +55,15 @@ public class SybaseCallMetaDataProvider extends GenericCallMetaDataProvider {
}
}
@Override
public String namedParameterBindingToUse(@Nullable String parameterName) {
return parameterName + " = ?";
}
@Override
public boolean byPassReturnParameter(String parameterName) {
return (RETURN_VALUE_NAME.equals(parameterName) ||
RETURN_VALUE_NAME.equals(parameterNameToUse(parameterName)));
}
@Override
public String namedParamBindingToUse(@Nullable String paramName) {
return paramName + " = ?";
}
}