While executing daoMethod() I am getting the following exception:
java.sql.SQLException: Procedure or function ‘Get_Books’ expects parameter ‘@totalRowsReturned’, which was not supplied.
Why? I did define @totalRowsReturned as OUTPUT. And I do not understand why I am required to supply @totalRowsReturned – it is an output parameter, not input.
Dao Class:
public class BookDao {
@Autowired
DataSource dataSource;
public void daoMethod() {
Integer programIdLocal = null;
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("bookId", 1);
MyStoredProcedure storedProcedure = new MyStoredProcedure(dataSource);
//Exception!!!!
Map<String, Object> results = storedProcedure.execute(parameters);
}
private class MyStoredProcedure extends StoredProcedure {
private static final String SQL = "dbo.Get_Books";
public MyStoredProcedure(DataSource dataSource) {
setDataSource(dataSource);
setFunction(true);
setSql(SQL);
declareParameter(new SqlReturnResultSet("rs", new BookMapper()));
declareParameter(new SqlOutParameter("totalRowsReturned", Types.INTEGER));
declareParameter(new SqlParameter("bookId", Types.INTEGER));
setFunction(true);
compile();
}
}
}
Stored Procedure:
CREATE PROCEDURE [dbo].[Get_Books]
@bookId int,
@totalRowsReturned int OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @SelectQuery NVARCHAR(2000)
DECLARE @first_id int
DECLARE @totalRows int
SET @SelectQuery = 'FROM books b WHERE b.book_id >= @bookId'
Set @SelectQuery = 'SELECT @first_id = b.book_id , @totalRows=Count(*) OVER() ' + @SelectQuery + ' ORDER BY b.book_id'
Execute sp_Executesql @SelectQuery, N'@first_id int, @bookId int, @totalRows int OUTPUT', @first_id, @bookId, @totalRows=@totalRowsReturned OUTPUT
END
There’s a important caveat in the Javadoc for
StoredProcedure#declareParameter()that you must declare the parameters in the order they are declared in the stored procedure, presumably because the same restriction exists for the underlyingCallableStatementclass. That means you should be declaring@bookIdbefore@totalRowsReturned.Also, I’m not all that knowledgable about JdbcTemplate but, based on this example, I don’t think you need to declare a result set parameter.