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 例外がスローされます。

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

だから私は正常に を埋めました@temp_table、私は接続を閉じず、stmtこれから結果セットを取得しようとし@temp_tableます。しかし、SQL は、このテーブルをまだ宣言していないと言っています。どのように可能ですか?

-- 解決済み --

クエリを 1 つだけ作成します。

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 仕様に従って、一度に実行できるステートメントは 1 つだけです。SQL Server JDBC ドライバーが 1 回の実行で複数のステートメントを実行できることは、標準からの逸脱です。また、次のようなことを行うことは、ドライバーを矛盾した状態にする可能性があるため、 JDBC でメソッド ( など)USE databasenameを使用するという推奨事項に反することに注意してください。ConnectionsetCatalog

あなたの特定の問題に関して、私には2つの理論があります(これらが実際の原因であるかどうかは確認していません):

  1. 自動コミットが有効になっています。ステートメントの実行後、接続がコミットされ、一時テーブルが破棄されます。
  2. ステートメントの実行後、クエリ コンテキストはサーバーによって破棄されるため、後続の実行では一時テーブルにアクセスできません。

これらは理論であり、1.が最も可能性が高いと思います。そのため、自動コミットを無効にしてみてください ( Connection.setAutoCommit(false))。

理論 2. が原因である場合は、それらを一度に実行し、複数の結果 (カウントと結果セット) を処理する必要があります。このStatement.execute(...)ために、複数の結果を使用して処理します。Java SQLに対する私の回答を参照してください: Statement.hasResultSet()? 複数の結果を処理する方法の例。

この最後の解決策は、自動コミットを無効にしたくない場合にも機能する可能性があります。

于 2014-08-15T11:11:44.243 に答える