Simplejdbccall存储过程withNamedBinding true

时间:2019-02-01 07:02:23

标签: sql-server spring-jdbc simplejdbccall

我想用SimpleJdbcCall用动态参数执行存储过程。在SQL Server SP中,我总共有6个可选参数,其中我必须能够传递任何或不传递任何参数。我的SP在MS Studio中按预期执行得很好。但不是通过SimpleJdbcCall。我以多种方式尝试过,其中一种是withNamedBinding。但这会在“ =”附近产生输入语法错误,如下所示。

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);

日志:

  

2019-01-31 18:14:49调试SimpleJdbcCall:405-以下   参数用于调用{call dbo.EmployeeDetails(empCode =>?,   empName =>?,empLoc =>?)}和{empCode = 0,empName ='hgkghdkgf',   empLoc ='kjhjk'} 2019年1月31日18:14:49 DEBUG DispatcherServlet:993-   无法完成请求   org.springframework.jdbc.UncategorizedSQLException:   CallableStatementCallback;未分类的SQLException for SQL [{call   dbo.EmployeeDetails(empCode =>?,empName =>?,empLoc =>?)}];的SQL   状态[S0001];错误代码[102]; '='附近的语法不正确。嵌套的   例外是com.microsoft.sqlserver.jdbc.SQLServerException:   '='附近的语法不正确。

1 个答案:

答案 0 :(得分:0)

我曾经遇到过类似的问题,并且在this堆栈溢出问题中找不到解决方案。但就我而言,我使用的是MS-SQL服务器,它给了我同样的语法错误。在寻找解决方案时,我遇到了this的Spring示例(请参见 11.5.6。声明要用于SimpleJdbcCall的参数)。 以防万一该链接不可用,这就是它的意思

我们可以选择显式声明一个,一些或所有参数。参数元数据仍在使用。通过调用方法withoutProcedureColumnMetaDataAccess,我们可以指定我们希望绕过对元数据查找进行任何潜在参数的处理,而仅使用声明的参数。可能出现的另一种情况是,一个或多个参数具有默认值,我们希望将其排除在调用之外。为此,我们只需调用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服务器并产生语法错误。 因此,在上述解决方案中,解决方法是

  1. 不要使用.withNamedBinding()方法。
  2. 使用.withoutProcedureColumnMetaDataAccess()方法。
  3. 在将参数数组传递给.useInParameterNames()方法时,请确保按proc中声明的顺序传递它(因为我们没有使用名称绑定)。我的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);

尝试一下,看看它是否对您有用。