NullPointerException с CallableStatement.getResultSet()

У меня есть хранимая процедура в SQL Server 2005, которая выглядит следующим образом (упрощенно):

CREATE PROCEDURE FOO
 @PARAMS
AS
BEGIN
  -- STEP 1: POPULATE tmp_table
  DECLARE @tmp_table TABLE (...)
  INSERT INTO @tmp_table
      SELECT * FROM BAR

  -- STEP 2: USE @tmp_table FOR FINAL SELECT
  SELECT abc, pqr
    FROM BAZ JOIN @tmp_table 
    ON some_criteria
END

Когда я запускаю этот процесс из SQL Server Management Studio, все работает нормально. Однако, когда я вызываю тот же процесс из программы Java, используя что-то вроде:

cs = connection.prepareCall("exec proc ?,");
cs.setParam(...);
rs = cs.getResultSet(); // BOOM - Null!

while(rs.next()) {...} // NPE!

Я не понимаю, почему первый возвращаемый набор результатов равен NULL. Может кто-то объяснить это мне?

В качестве обходного пути, если я проверю cs.getMoreResults() и если это правда, попробуйте еще один getResultSet() - НА ЭТОТ раз он возвращает правильный набор результатов.

Любые указатели, пожалуйста? (Я использую драйверы JTDS, если это имеет значение)

Спасибо, Радж


person ragebiswas    schedule 16.06.2010    source источник
comment
ммм. Вы когда-нибудь звонили cs.execute() или cs.executeQuery()?   -  person clstrfsck    schedule 16.06.2010
comment
Взгляните на этот ответ здесь. Я ясно объясняю, как результаты возвращаются из базы данных и как вы должны анализировать свои наборы результатов. stackoverflow.com/a/66455195/4884153   -  person chargedfever    schedule 08.03.2021


Ответы (2)


Javadoc для getResultSet() говорит, что возвращает null "... если результатом является количество обновлений или результатов больше нет". Похоже, что ваша хранимая процедура будет иметь счетчик обновлений и набор результатов, и что метод getResultSet() (возможно) просто делает то, что согласно контракту API он должен делать.

Вы можете попробовать сначала получить количество обновлений. В противном случае придерживайтесь своего «обходного пути».

person Stephen C    schedule 16.06.2010
comment
Да. Также я заметил одну вещь: executeQuery() работает все время (никогда не возвращает null). Все равно приму твой ответ... - person ragebiswas; 16.06.2010
comment
@Raj - предположительно, если вы выполняете с помощью executeQuery, невозможно получить количество обновлений. (Вопрос - действительно ли можно получить количество обновлений из INSERT?) - person Stephen C; 16.06.2010

Думаю, бессмысленно публиковать ответ после того, как был выбран правильный ответ.

Решение, которое я предлагаю, звонит

set nocount on

перед оператором вставки и

set nocount off

после. В противном случае вставки возвращают набор результатов.

person Chip McCormick    schedule 16.11.2011