Запросы, возвращающие несколько наборов результатов

У меня есть база данных 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

Ответ: это НЕ возможно. Единственный способ: запустить их как отдельные запросы.