Я использую Spring Framework StoredProcedure
(я, конечно, расширяю его), чтобы получить набор результатов и выходной параметр (@totalRowsReturned
), который является целым числом.Проблема в том, что когда возвращаемый набор результатов должен быть пустым списком, я получаю NullPointerException
, когда пытаюсь получить выходной параметр (totalRows, который наивно я ожидал бы, что он будет нулевым).
Хочу отметить, что код работает нормально, когда найденный набор результатов не пустой.
Мои вопросы:
Почему в этом случае @totalRowsReturned
не устанавливается на ноль?(Или, если это так, почему я не могу получить его через код Java?)
Как я могу заставить этот код (код Java + код T-SQL) работать таким образомспособ, которым @totalRowsReturned
будет установлен в ноль при необходимости, и я мог бы получить его через код Java?
Dao:
List<Book> books = null;
int totalRows = 0;
Map<String, Object> results = storedProcedure.execute(parameters);
books = (List<Book>) results.get("rs");
totalRows = (Integer) results.get("totalRowsReturned"); // NullPointerException on this line if total rows are supposed to be zero!!
хранимая процедура T-SQL:
CREATE PROCEDURE Find_Books
@authorName Varchar(250),
@totalRowsReturned INTEGER OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @SelectQuery NVARCHAR(2000)
SET @SelectQuery = 'SELECT @totalRows=COUNT(*) OVER() FROM book b WHERE b.author_name = @authorName'
Execute sp_Executesql @SelectQuery, N'@authorName VARCHAR(250), @totalRows int OUTPUT', @authorName, @totalRows=@totalRowsReturned OUTPUT
-- Select resultset goes here...
END
ОБНОВЛЕНИЕ:
На самом деле моя хранимая процедура выглядит примерно так (изменениеявляется дополнительным @first_id = b.book_id
в SELECT):
CREATE PROCEDURE Find_Books
@authorName Varchar(250),
@totalRowsReturned INTEGER OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @SelectQuery NVARCHAR(2000)
DECLARE @first_id int
DECLARE @first_id_local_returned int
SET @SelectQuery = 'SELECT @first_id = b.book_id, @totalRows=COUNT(*) OVER() FROM book b WHERE b.author_name = @authorName'
Execute sp_Executesql @SelectQuery, N'@authorName VARCHAR(250), @first_id int OUTPUT, @totalRows int OUTPUT', @authorName, @first_id=@first_id_local_returned OUTPUT, @totalRows=@totalRowsReturned OUTPUT
-- Select resultset goes here... I am using the value of @first_id_local_returned in this SELECT...
END
Проблема в том, что когда нет строк, возвращаемых из SELECT, b.book_id не определен, поэтому яполучить org.springframework.dao.TransientDataAccessResourceException ... Column 'book.book_id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Таким образом, похоже, что если я сохраню OVER()
, то @totalRows=COUNT(*) OVER()
завершится неудачно, когда будет возвращено ноль строк, и если я удалю OVER()
,тогда @first_id = b.book_id
терпит неудачу.
Есть идеи, как мне это преодолеть?