通过Java获取已创建且已填充的MSSQL临时表的结果集

时间:2014-08-15 09:42:14

标签: java sql-server jdbc sqljdbc

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连接并尝试从此@temp_table获取Resultset。但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 个答案:

答案 0 :(得分:1)

从技术上讲,遵循JDBC规范,您一次只能执行一条语句。 SQL Server JDBC驱动程序允许在一次执行中执行多个语句是标准的偏差。另请注意,像USE databasename这样的操作违反了JDBC中使用Connection方法(如setCatalog)的建议,因为它可能会使驱动程序处于不一致状态。

至于你的具体问题,我有两个理论(我没有证实这些是否是实际原因):

  1. 您已启用自动提交。执行语句后,将提交连接,并释放临时表。
  2. 在语句执行后,服务器会处理查询上下文,因此后续执行无法访问临时表。
  3. 这些是理论,我相信1.最有可能。因此,请尝试禁用自动提交(Connection.setAutoCommit(false))。

    如果理论2.是原因,那么你需要一次执行它们,并处理多个结果(计数和结果集)。为此,您将使用Statement.execute(...)并处理多个结果。有关如何处理多个结果的示例,请参阅我对Java SQL: Statement.hasResultSet()?的回答。

    如果您不想禁用自动提交,那么最后一个解决方案也可能有效。