使用 StoredProcedureItemReader 时出现 SQLServerException
SQLServerException when using StoredProcedureItemReader
我在尝试使用 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 存储过程时,它 运行 很好,并让我得到由来自不同表的 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
....
谁能告诉我如何解决这个问题。提前致谢!
您需要确保在存储过程本身中设置 SET NOCOUNT ON
以避免此错误。不需要输出参数,但行数作为一个返回。
你又是运行直接存储程序SQL服务器如下:
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)};
即一个输出参数和两个输入参数。
在我将 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)};
我在尝试使用 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 存储过程时,它 运行 很好,并让我得到由来自不同表的 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
....
谁能告诉我如何解决这个问题。提前致谢!
您需要确保在存储过程本身中设置 SET NOCOUNT ON
以避免此错误。不需要输出参数,但行数作为一个返回。
你又是运行直接存储程序SQL服务器如下:
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)};
即一个输出参数和两个输入参数。
在我将 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)};