2

查询5

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)";

查询3

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 Exception 抛出错误;

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

所以我成功填充了@temp_table,我没有关闭stmt连接并尝试从中获取结果集@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();
}
4

1 回答 1

1

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

至于您的具体问题,我有两种理论(我尚未验证这些是否是实际原因):

  1. 您已启用自动提交。语句执行后,连接被提交,临时表被释放。
  2. 在语句执行后,查询上下文由服务器处理,因此后续执行无法访问临时表。

这些都是理论,我相信 1. 是最有可能的。所以尝试禁用自动提交(Connection.setAutoCommit(false))。

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

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

于 2014-08-15T11:11:44.243 回答