【问题标题】:SQLServerException when using StoredProcedureItemReader使用 StoredProcedureItemReader 时出现 SQLServerException
【发布时间】:2020-10-07 14:18:27
【问题描述】:

我在尝试使用 StoredProcedureItemReader 时遇到错误。

我有一个用 Microsoft SQL 服务器编写的存储过程,它具有以下输入和输出参数:
存储过程名称: person_details
输入: @From, @To
输出是来自不同表的不同列的组合。

这是我的代码:

    StoredProcedureItemReader<ClaimExtractDTO> reader = new StoredProcedureItemReader<>();

    SqlParameter[] parameter = {new SqlParameter("@From", java.sql.Types.BIGINT), new SqlParameter("@To", java.sql.Types.BIGINT)};

    PreparedStatementSetter statementValues = new PreparedStatementSetter() {
        @Override
        public void setValues(PreparedStatement ps) throws SQLException {
            ps.setLong(1, minValue); //minValue - Input 1
            ps.setLong(2, maxValue); //maxValue - Input 2
        }
    };  
    reader.setDataSource(dataSource);
    reader.setProcedureName("dbo.person_details");
    reader.setParameters(parameter);
    reader.setPreparedStatementSetter(statementValues);
    reader.setRowMapper(new BeanPropertyRowMapper<>(ClaimExtractDTO.class));    
    return reader;

当运行上面的代码时,我得到了

Caused by: org.springframework.dao.TransientDataAccessResourceException: Executing stored procedure; SQL [{call dbo.person_details(?, ?)}]; The index 0 of the output parameter is not valid.; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: The index 0 of the output parameter is not valid.
    at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:110) ~[spring-jdbc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) ~[spring-jdbc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.batch.item.database.StoredProcedureItemReader.openCursor(StoredProcedureItemReader.java:229) ~[spring-batch-infrastructure-4.2.3.BUILD-SNAPSHOT.jar:4.2.3.BUILD-SNAPSHOT]
    at org.springframework.batch.item.database.AbstractCursorItemReader.doOpen(AbstractCursorItemReader.java:428) ~[spring-batch-infrastructure-4.2.3.BUILD-SNAPSHOT.jar:4.2.3.BUILD-SNAPSHOT]
    at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:150) ~[spring-batch-infrastructure-4.2.3.BUILD-SNAPSHOT.jar:4.2.3.BUILD-SNAPSHOT]
    ... 18 common frames omitted
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The index 0 of the output parameter is not valid.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:234) ~[mssql-jdbc-7.4.1.jre8.jar:na]
    at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getterGetParam(SQLServerCallableStatement.java:403) ~[mssql-jdbc-7.4.1.jre8.jar:na]
    at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getObject(SQLServerCallableStatement.java:705) ~[mssql-jdbc-7.4.1.jre8.jar:na]
    at com.zaxxer.hikari.pool.HikariProxyCallableStatement.getObject(HikariProxyCallableStatement.java) ~[HikariCP-3.4.5.jar:na]
    at org.springframework.batch.item.database.StoredProcedureItemReader.openCursor(StoredProcedureItemReader.java:222) ~[spring-batch-infrastructure-4.2.3.BUILD-SNAPSHOT.jar:4.2.3.BUILD-SNAPSHOT]
    ... 20 common frames omitted

当我使用exec dbo.person_details '1', '100'; 在 SQL Server 上运行存储过程时,它运行良好,并为我提供了包含来自不同表的 20 列的输出。

我什至在程序上设置了set nocount on

我用SqlParameter[] parameter = {new SqlOutParameter("personKey", java.sql.Types.INTEGER), new SqlParameter("@From", java.sql.Types.BIGINT), new SqlParameter("@To", java.sql.Types.BIGINT)}; 尝试过,认为应该定义超参数。我仍然遇到上面提到的相同错误。

程序的主要内容:

USE [employee]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
set nocount on
GO

ALTER PROCEDURE [dbo].[person_details]
@From   BIGINT,
@To     BIGINT
AS
....

谁能告诉我如何解决这个问题。提前致谢!

【问题讨论】:

    标签: sql-server spring-boot spring-batch batch-processing


    【解决方案1】:

    您需要确保在存储过程本身内设置SET NOCOUNT ON 以避免此错误。不需要输出参数,但行数返回为 1。

    您还直接再次运行 SQL Server 存储过程,如下所示:

    exec dbo.person_details '1', '100';
    

    即两个输入参数,没有输出参数。

    但在您的代码中,您将参数设置如下:

    SqlParameter[] parameter = {new SqlOutParameter("personKey", java.sql.Types.INTEGER), new SqlParameter("@From", java.sql.Types.BIGINT), new SqlParameter("@To", java.sql.Types.BIGINT)};
    

    即一个输出参数和两个输入参数。

    【讨论】:

    • 我已经删除了 SqlOutParameter 它仍然不起作用
    • 我通过删除 SqlOutParameter 来编辑代码。我仍然遇到同样的错误
    • 你能发布存储过程吗?不一定是内部 - 只是声明和参数。
    • 我删除了代码中的 SqlOutParameter。即使使用 SqlOutParameter 而没有 SqlOutParameter,我仍然会遇到相同的错误。另外,我在帖子中添加了程序的主要内容。
    • 您是否在程序中设置set nocount on?您发布的代码在运行 ALTER PROCEDURE 之前对其进行了设置,这在调用时不会影响过程本身的设置。
    【解决方案2】:

    在我将set nocount on 放入我的程序后它可以工作

    USE [employee]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER PROCEDURE [dbo].[person_details]
    @From   BIGINT,
    @To     BIGINT
    AS
    set nocount on;
    

    我的 SQLParameters 看起来像

    SqlParameter[] parameter = {new SqlParameter("@From", java.sql.Types.BIGINT), new SqlParameter("@To", java.sql.Types.BIGINT)};
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-02
      • 1970-01-01
      • 2015-06-13
      • 1970-01-01
      相关资源
      最近更新 更多