1
votes

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
1

1 Answers

3
votes

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 underlying CallableStatement class. That means you should be declaring @bookId before @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.