Получить Resultset созданной и заполненной временной таблицы MSSQL через Java

query5

String query5 ="USE DBTwo\n" +
    "DECLARE @temp_table table (column1 VARCHAR(60))\n" +
    "insert into @temp_table (column1)\n" +
    "select column1 from real_table (nolock)";

query3

String query3 = "USE DBTwo\n" +
    "select column1 from @temp_table";

Соединения;

ResultSet rs1;
Statement stmt;

Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String connectionUrl = "jdbc:sqlserver://192.168.131.10;" +"databaseName=DBOne;" +"user=" + "exuser" + ";" + "password="+"userpass" + ";" + "allowMultiQueries=true" + ";"; 
Connection con = DriverManager.getConnection(connectionUrl);
stmt = con.createStatement();

Получение результатов;

   try {
       int rowcount = stmt.executeUpdate(query5);
       System.out.println(rowcount);

       rs1 = stmt.executeQuery(query3);
       while (rs1.next()) {
             System.out.println(rs1.getString(1)); 
       } 
        rs1.close();
   }
   catch (SQLException sqlex){
       sqlex.printStackTrace();
   }

Sql Исключение бросить ниже ошибки;

com.microsoft.sqlserver.jdbc.SQLServerException: Must declare the table variable "@temp_table".`rowcount` return 7 

так что я успешно заполнил @temp_tableЯ не закрываю stmt подключиться и попытаться получить Resultset из этого @temp_table, Но SQL говорит, что я еще не объявил эту таблицу. Как это возможно?

- решено -

Создание только одного запроса;

String query5 ="USE DBTwo\n" +
"DECLARE @temp_table table (column1 VARCHAR(60))\n" +
"insert into @temp_table (column1)\n" +
"select column1 from real_table(nolock)\n" +
"select column1 from @temp_table";

Получить несколько результатов, как показано ниже;

try {
  boolean result = stmt.execute(query5);
  while (true)
   if(result){
    rs1 = stmt.getResultSet();
    while (rs1.next()) {
    System.out.println(rs1.getString(1)); 
    }

  } else {
    int updateCount = stmt.getUpdateCount();
    if (updateCount == -1){
    break; 
  }
    result = stmt.getMoreResults();
}
catch (SQLException sqlex){
   sqlex.printStackTrace();
}

1 ответ

Решение

Технически, следуя спецификации JDBC, вам разрешено выполнять только одну инструкцию за раз. То, что драйвер JDBC для SQL Server позволяет выполнять несколько операторов за одно выполнение, является отклонением от стандарта. Также обратите внимание, что делать такие вещи, как USE databasename противоречит рекомендации в JDBC использовать Connection методы (как setCatalog) для этого, так как это может привести водителя в противоречивое состояние.

Что касается вашей конкретной проблемы, у меня есть две теории (я не проверял, являются ли они реальной причиной):

  1. У вас включена автоматическая фиксация. После выполнения инструкции соединение фиксируется и временная таблица удаляется.
  2. После выполнения оператора контекст запроса удаляется сервером, поэтому последующее выполнение не имеет доступа к временной таблице.

Это теории, и я считаю, что 1. является наиболее вероятным. Поэтому попробуйте отключить автоматическую фиксацию (Connection.setAutoCommit(false)).

Если теория 2. является причиной, то вам нужно выполнить их за один раз и обработать несколько результатов (подсчет и набор результатов). Для этого вы бы использовали Statement.execute(...) и обрабатывать для нескольких результатов. Смотрите мой ответ на Java SQL: Statement.hasResultSet()? для примера о том, как обрабатывать несколько результатов.

Последнее решение, вероятно, также работает, если вы не хотите отключать автоматическую фиксацию.

Другие вопросы по тегам