From 748dd94dabd237eb23f6f8516c4235432a6d65eb Mon Sep 17 00:00:00 2001 From: Giuseppe Milicia Date: Wed, 29 Mar 2023 20:49:41 +0200 Subject: [PATCH] Fix Sybase SimpleJdbcCall named parameter binding --- .../jdbc/core/metadata/CallMetaDataContext.java | 4 +++- .../jdbc/core/metadata/CallMetaDataProvider.java | 7 +++++++ .../core/metadata/GenericCallMetaDataProvider.java | 10 ++++++++++ .../core/metadata/SybaseCallMetaDataProvider.java | 5 +++++ .../jdbc/core/simple/SimpleJdbcCallTests.java | 13 +++++++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java index 07650a89041a..2c3694667af5 100755 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java @@ -676,7 +676,9 @@ public String createCallString() { * @since 4.2 */ protected String createParameterBinding(SqlParameter parameter) { - return (isNamedBinding() ? parameter.getName() + " => ?" : "?"); + Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available"); + + return (isNamedBinding() ? this.metaDataProvider.namedParamBindingToUse(parameter.getName()) : "?"); } private static String lowerCase(@Nullable String paramName) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProvider.java index 8cf32bb84822..a6d88d52a818 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProvider.java @@ -180,4 +180,11 @@ void initializeWithProcedureColumnMetaData(DatabaseMetaData databaseMetaData, @N */ 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); + } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java index 1ae9ff0e67d3..0f63d12c5721 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java @@ -246,6 +246,16 @@ public boolean isSupportsSchemasInProcedureCalls() { 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. */ diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/SybaseCallMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/SybaseCallMetaDataProvider.java index 5d590a99c8c3..c2f84e47758e 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/SybaseCallMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/SybaseCallMetaDataProvider.java @@ -60,4 +60,9 @@ public boolean byPassReturnParameter(String parameterName) { RETURN_VALUE_NAME.equals(parameterNameToUse(parameterName))); } + @Override + public String namedParamBindingToUse(@Nullable String paramName) { + return paramName + " = ?"; + } + } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcCallTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcCallTests.java index b99cd1591da2..440d1d2aecd8 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcCallTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcCallTests.java @@ -349,4 +349,17 @@ private void verifyAddInvoiceWithMetaData(boolean isFunction) throws SQLExceptio verify(procedureColumnsResultSet).close(); } + @Test + void correctSybaseFunctionStatementNamed() throws Exception { + given(databaseMetaData.getDatabaseProductName()).willReturn("Sybase"); + SimpleJdbcCall adder = new SimpleJdbcCall(dataSource) + .withoutProcedureColumnMetaDataAccess() + .withNamedBinding() + .withProcedureName("ADD_INVOICE") + .declareParameters(new SqlParameter("@AMOUNT", Types.NUMERIC)) + .declareParameters(new SqlParameter("@CUSTID", Types.NUMERIC)); + adder.compile(); + verifyStatement(adder, "{call ADD_INVOICE(@AMOUNT = ?, @CUSTID = ?)}"); + } + }