Sql server 名为Binding true的SimpleJDBCall存储过程

Sql server 名为Binding true的SimpleJDBCall存储过程,sql-server,spring-jdbc,simplejdbccall,Sql Server,Spring Jdbc,Simplejdbccall,我想用SimpleJDBCall执行带有动态参数的存储过程。我在SQL server SP中总共有6个可选参数,其中我必须能够传递任何参数或不传递任何参数。我的SP在MS Studio中按预期运行良好。但不是SimpleJDBCall。我尝试了很多种方法,其中一种方法是命名绑定。但它给出了“=”附近的输入语法错误,如下所示 this.simpleJdbcCall = new SimpleJdbcCall(jdbcTemplateObject) .withN

我想用SimpleJDBCall执行带有动态参数的存储过程。我在SQL server SP中总共有6个可选参数,其中我必须能够传递任何参数或不传递任何参数。我的SP在MS Studio中按预期运行良好。但不是SimpleJDBCall。我尝试了很多种方法,其中一种方法是命名绑定。但它给出了“=”附近的输入语法错误,如下所示

this.simpleJdbcCall = new SimpleJdbcCall(jdbcTemplateObject)
                    .withNamedBinding()
                    .withSchemaName("dbo")
                    .withProcedureName("EmployeeDetails")
                    .useInParameterNames(
                            paramNameArray)
                    .returningResultSet("detailReportData", BeanPropertyRowMapper.newInstance(Employee.class));
            Map<String,Object> out = this.simpleJdbcCall.execute(sqlSource);
this.simpleJdbcCall=newsimplejdbccall(jdbcTemplateObject)
.withNamedBinding()
.使用Chemaname(“dbo”)
.使用程序重命名(“员工详细信息”)
.UseinParameterName(
参数(数组)
.returningResultSet(“detailReportData”,BeanPropertyRowMapper.newInstance(Employee.class));
Map out=this.simpleJdbcCall.execute(sqlSource);
日志:

2019-01-31 18:14:49调试SimpleJDBCall:405-以下 参数用于调用{call dbo.EmployeeDetails(empCode=>?, empName=>?,empLoc=>?)},带有{empCode=0,empName='hgkghdkgf', empLoc='kjhjk'}2019-01-31 18:14:49调试调度员服务:993- 无法完成请求 org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback;SQL[{调用的未分类SQLException dbo.EmployeeDetails(empCode=>?,empName=>?,employoc=>?)}];SQL 状态[S0001];错误代码[102];“=”附近的语法不正确。;嵌套 异常为com.microsoft.sqlserver.jdbc.SQLServerException: “=”附近的语法不正确


我曾经遇到过类似的问题,在堆栈溢出问题上几乎找不到解决方案。但在我的例子中,我使用的是MS-SQL server,它给了我同样的语法错误。在搜索解决方案时,我遇到了Spring的示例(请参见第11.5.6节,声明用于SimpleJDBCall的参数)。 以防链接不可用,下面是它的说明

我们可以选择显式声明一个、部分或全部参数。参数元数据仍在使用中。通过调用WithOutProcedureRecolumnMetadataAccess方法,我们可以指定希望绕过对潜在参数的元数据查找的任何处理,而只使用声明的参数。另一种可能出现的情况是,一个或多个in参数具有默认值,我们希望将它们排除在调用之外。为此,我们只需调用useInParameterNames来指定要包含的in参数名列表

下面是示例代码

public class JdbcActorDao implements ActorDao {
private SimpleJdbcCall procReadActor;

public void setDataSource(DataSource dataSource) {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    jdbcTemplate.setResultsMapCaseInsensitive(true);
    this.procReadActor =
            new SimpleJdbcCall(jdbcTemplate)
                    .withProcedureName("read_actor")
                    .withoutProcedureColumnMetaDataAccess()
                    .useInParameterNames("in_id")
                    .declareParameters(
                            new SqlParameter("in_id", Types.NUMERIC),
                            new SqlOutParameter("out_first_name", Types.VARCHAR),
                            new SqlOutParameter("out_last_name", Types.VARCHAR),
                            new SqlOutParameter("out_birth_date", Types.DATE)
                    );
}


//  ... additional methods
}

我不知道为什么,但withNamedBinding()方法似乎无法与ms sql server一起正常工作,并导致语法错误。 因此,在上述解决方案中,解决方法是

  • 不要使用.withNamedBinding()方法
  • 使用.WithOutProcedureRecolumnMetadataAccess()方法
  • 在将参数数组传递给.useInParameterNames()方法时,请确保按照过程中声明的顺序传递它(因为我们没有使用名称绑定)。我的out参数在最后一个参数之前声明了几个参数,因此在将var转换为int时,它给了我错误,因为我的out参数是int
  • 因此,现在您的解决方案应该如下所示:

    this.simpleJdbcCall = new SimpleJdbcCall(jdbcTemplateObject)
                    .withSchemaName("dbo")
                    .withProcedureName("EmployeeDetails")
                    .withoutProcedureColumnMetaDataAccess()
                    .useInParameterNames(paramNameArray)
                    .returningResultSet("detailReportData", BeanPropertyRowMapper.newInstance(Employee.class));
            Map<String,Object> out = this.simpleJdbcCall.execute(sqlSource);
    
    this.simpleJdbcCall=newsimplejdbccall(jdbcTemplateObject)
    .使用Chemaname(“dbo”)
    .使用程序重命名(“员工详细信息”)
    .withoutProcedureRecolumnMetadataAccess()的
    .useInParameterNames(paramNameArray)
    .returningResultSet(“detailReportData”,BeanPropertyRowMapper.newInstance(Employee.class));
    Map out=this.simpleJdbcCall.execute(sqlSource);
    
    试一试,看看这是否适合你