Запросы, возвращающие несколько наборов результатов
У меня есть база данных MSSQL
, и я запускаю следующий запрос:
select * from projects; select * from user
Вышеприведенный запрос возвращает сразу два набора результатов, и я не могу запускать оба запроса отдельно. Как я могу обрабатывать оба набора результатов сразу в классе Java?
Ответы
Ответ 1
Правильный код для обработки нескольких ResultSet
возвращаемых оператором JDBC:
PreparedStatement stmt = ...;
boolean isResultSet = stmt.execute();
int count = 0;
while(true) {
if(isResultSet) {
rs = stmt.getResultSet();
while(rs.next()) {
processEachRow(rs);
}
rs.close();
} else {
if(stmt.getUpdateCount() == -1) {
break;
}
log.info("Result {} is just a count: {}", count, stmt.getUpdateCount());
}
count ++;
isResultSet = stmt.getMoreResults();
}
Важные биты:
-
getMoreResults()
и execute()
вернуть false
чтобы указать, что результат оператора - это просто номер, а не ResultSet
. - Вам нужно проверить
stmt.getUpdateCount() == -1
чтобы узнать, есть ли больше результатов. - Убедитесь, что вы либо закрываете результирующие наборы, либо используете
stmt.getMoreResults(Statement.CLOSE_CURRENT_RESULT)
Ответ 2
Вы можете использовать Statement.execute(), getResultSet();
PreparedStatement stmt = ... prepare your statement result
boolean hasResults = stmt.execute();
while (hasResults) {
ResultSet rs = stmt.getResultSet();
... your code parsing the results ...
hasResults = stmt.getMoreResults();
}
Ответ 3
Да, вы можете. См. Статью MSDN
https://msdn.microsoft.com/en-us/library/ms378758(v=sql.110).aspx
public static void executeStatement(Connection con) {
try {
String SQL = "SELECT TOP 10 * FROM Person.Contact; " +
"SELECT TOP 20 * FROM Person.Contact";
Statement stmt = con.createStatement();
boolean results = stmt.execute(SQL);
int rsCount = 0;
//Loop through the available result sets.
do {
if(results) {
ResultSet rs = stmt.getResultSet();
rsCount++;
//Show data from the result set.
System.out.println("RESULT SET #" + rsCount);
while (rs.next()) {
System.out.println(rs.getString("LastName") + ", " + rs.getString("FirstName"));
}
rs.close();
}
System.out.println();
results = stmt.getMoreResults();
} while(results);
stmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
Я тестировал это, и он отлично работает.
Ответ 4
public static void executeProcedure(Connection con) {
try {
CallableStatement stmt = con.prepareCall(...);
..... //Set call parameters, if you have IN,OUT, or IN/OUT parameters
boolean results = stmt.execute();
int rsCount = 0;
//Loop through the available result sets.
while (results) {
ResultSet rs = stmt.getResultSet();
//Retrieve data from the result set.
while (rs.next()) {
....// using rs.getxxx() method to retieve data
}
rs.close();
//Check for next result set
results = stmt.getMoreResults();
}
stmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
Ответ 5
Прежде чем использовать java, вам нужно посмотреть предложение RESULT SETS.
У MSSQL есть эта функция, которая может помочь вам с вашим java-кодом, более практичным способом.
В этом примере будут выполняться два запроса:
EXEC('SELECT id_person, name, age FROM dbo.PERSON; SELECT id_url, url FROM dbo.URL;')
WITH RESULT SETS
(
(
id_person BIGINT,
name VARCHAR(255),
age TINYINT
),
(
id_url BIGINT,
url VARCHAR(2000)
)
);
Вы также можете использовать хранимые процедуры с РЕЗУЛЬТАТЫ РЕЗУЛЬТАТОВ.
Подробнее о: https://technet.microsoft.com/en-us/library/ms188332(v=sql.110).aspx
Ответ 6
Подход UNION, предложенный Акашем и Юргеном, жизнеспособен, но требует немного больше работы:
- Определите, какие столбцы разделены обеими таблицами.
- Определите, какие столбцы относятся к одной из таблиц.
- Напишите запрос, объединяющий все столбцы из обеих таблиц, с общими столбцами, отображаемыми в тех же местах в обоих предложениях, и с нулевыми значениями, заменяющими столбцы, относящиеся к конкретной таблице. Вероятно, вы также захотите, чтобы столбец указывал, какие строки пришли из этих таблиц.
Итак, например, рассмотрим таблицы со следующими структурами:
Projects
--------
ID
Name
Budget
Users
-----
ID
Name
PhoneNo
Чтобы отобразить результаты из обеих таблиц, вы можете использовать такой запрос, как:
select 'Projects' table_name, ID, Name, null as PhoneNo, Budget from Projects
union all
select 'Users' table_name, ID, Name, PhoneNo, null as Budget from Users
В зависимости от вашей РСУБД вам может потребоваться явно преобразовать нули в требуемый тип данных.
Ответ 7
Запрос UNION ALL позволяет комбинировать результирующие наборы из 2 или более запросов "select". Он возвращает все строки (даже если строка существует более чем в одном из операторов "select" ).
Каждый оператор SQL в запросе UNION ALL должен иметь одинаковое количество полей в наборах результатов с похожими типами данных.........
select * from projects
UNION ALL
select * from user
Ответ 8
Ответ: это НЕ возможно. Единственный способ: запустить их как отдельные запросы.