Объект Java JDBC Single Statement перед циклом while и внутри цикла while - PullRequest
0 голосов
/ 15 марта 2019

Я пишу одну базовую Java-программу с JDBC для подключения к Oracle.

  • Я выбираю свою первую таблицу с условием выбора, чтобы получить несколько идентификаторов строк.Я получил несколько записей, выбранных в наборе результатов
  • Теперь я зацикливаю набор результатов в цикле while (while resultSet.next ())
  • Затем выбираю вторую таблицу для строк, идентификаторы которых равнык идентификаторам в 1-м наборе результатов

В обоих вариантах выбора я использую один и тот же объект Statement.Во время работы программы я получаю только данные 1-й строки, а затем java выдает ошибку, что набор результатов закрыт

Короче говоря, я хотел знать, могу ли я использовать один единственный объект Statement перед циклом и внутри цикла?

Ниже приведен пример кода

allCOBbatchRSet=stmt.executeQuery("SELECT RECID FROM V_F_BATCH WHERE BATCH_STAGE IS NOT NULL");
while (allCOBbatchRSet.next())
{
        BatchRSet=stmt.executeQuery("SELECT XMLRECORD FROM F_BATCH WHERE RECID="+cobBatchRecId);
        BatchRSet.next();
        ............
}

Не удалось, за исключением

java.sql.SQLException: Closed Resultset: next at
oracle.jdbc.driver.InsensitiveScrollableResultSet.ensureOpen(InsensitiveScrollableResultSet.java:109) at
oracle.jdbc.driver.InsensitiveScrollableResultSet.next(InsensitiveScrollableResultSet.java:398) at
com.manohar.t24.COBDetails.getCOBDetails(COBDetails.java:46) 

1 Ответ

0 голосов
/ 16 марта 2019

Вы не можете повторно использовать оператор, перебирая набор результатов, созданный этим оператором, для выполнения другого запроса (или любого другого типа оператора) для этого объекта Statement, который автоматически закроет набор результатов предыдущего выполнения запроса. Это требуется API JDBC и спецификацией.

Если вы хотите сделать это, вам нужно отключить автоматическую фиксацию * и использовать два объекта оператора.

Однако код, который вы показываете, является анти-шаблоном, известным как проблема запроса N + 1, в общем, вы не должны циклически повторять набор результатов для выполнения других отдельных выборок в строке: вы можете создать один оператор выбора, который это делает для тебя. Обычно это работает намного лучше.

Например, вы можете использовать:

select V_F_BATCH.RECID, F_BATCH.XMLRECORD 
from V_F_BATCH
inner join F_BATCH
  on F_BATCH.RECID = V_F_BATCH.RECID
where V_F_BATCH.BATCH_STAGE is not NULL 

Это также позволит избежать потенциальной проблемы с внедрением SQL в вашем текущем коде.


*: Отключение автоматической фиксации необходимо, поскольку JDBC требует выполнения любого оператора для фиксации в режиме автоматической фиксации. И фиксация также закроет открытые наборы результатов, если они не будут удерживаться над фиксацией (хотя некоторые драйверы JDBC снисходительны в этом отношении и набор результатов не будет закрыт на границе автоматической фиксации).

...