2011-12-14 14 views
8

This投稿は、1回のJDBC呼び出し(SQL Serverデータベースに対して)でセミコロンで区切って複数のクエリを実行することを示しました。 Oracle 10Gで同じことを試みたとき、「無効な文字」というエラーが発生しました:JDBC:1つのデータベース呼び出しで複数の結果セットを返す - Oracleでは機能しない

class db 
{ 
    public static void main(String aa[])throws Exception 
    { 
     Class.forName("oracle.jdbc.driver.OracleDriver"); 
     Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@//192.168.10.29:1521/ttt","username","password"); 
     PreparedStatement stat = conn.prepareStatement("select voila from app where rownum<4; select code from process where rownum<4"); 
     stat.execute(); 
     while (stat.getMoreResults()){ 
      ResultSet rs = stat.getResultSet(); 
      while (rs.next()){ 
       System.out.println(rs.getString(1));   
      } 
     } 
     conn.close(); 
    } 
} 

私は間違っていますか?

答えて

7

あなたは(すべてのDBMSが同じように機能することを前提とする以外)間違って何もしていません

オラクル(およびそのJDBCドライバ)は、単純にこの機能をサポートしていません。

各SELECTを個別に実行する必要があります。

Btw:これは、一部のSQLインジェクション攻撃がOrace、特に有名な "little bobby tables"の漫画では機能しない理由の1つです。

+0

ありがとうございました。しかし、私は2つの別のdbコールを行う必要はありませんような方法はありますか? – Daud

+1

2つの選択が同じタイプを返す場合は、共用体を使用できます。しかしそれは本当に悪い練習です –

+1

@Daud:いいえ、2回の呼び出しが必要です。 –

1

1回の呼び出しで複数の結果セットをOracleからJDBCに戻すことができます。それを行うにはいくつかの方法があります。 a good post at Oracle-Base shows how

私が使用するメカニズムは、呼び出し可能なステートメントで匿名ブロックを作成し、各結果セットに出力パラメータとしてSYS_REFCURSORをバインドすることです。

これだけのコードがあります。エラー処理のために怠惰ですが、それはアイデアを得る:

public void getMultiple() throws Exception { 

    // get connection 
    Connection conn = DriverManager.getConnection(TestConfig.JDBC_URL, TestConfig.DB_USERNAME, TestConfig.DB_PASSWORD); 

    // here's the statement; it uses an anonymous block. In that block, 
    // we've declared two SYS_REFCURSOR objects which are opened over our 
    // SELECT statements. Once the statements are opened, we bind the 
    // SYS_REFCURSOR objects so they can be retrieved from JDBC 
    String s = 
      "DECLARE" + 
      " l_rs1 SYS_REFCURSOR; " + 
      " l_rs2 SYS_REFCURSOR; " + 
      "BEGIN "+ 
      " OPEN l_rs1 FOR " + 
      "  SELECT 'Moose' FROM DUAL;" + 
      " OPEN l_rs2 FOR " + 
      "  SELECT 'Squirrel' FROM DUAL; " + 
      " ? := l_rs1;" + 
      " ? := l_rs2;" + 
      "END;"; 

    // prepare the callable statement, registering 
    // the output parameter we want 
    CallableStatement cs = conn.prepareCall(s); 
    cs.registerOutParameter(1, OracleTypes.CURSOR); 
    cs.registerOutParameter(2, OracleTypes.CURSOR); 

    // execute the callable statement 
    cs.execute(); 

    // retrieve the result sets by getting the bound output objects and 
    // casting them to Java ResultSet objects 
    ResultSet rs1 = (ResultSet) cs.getObject(1); 
    ResultSet rs2 = (ResultSet) cs.getObject(2); 

    // advance the first result set and print the string it yields 
    rs1.next(); 
    System.out.printf("Result set 1 has '%s'\n", rs1.getString(1)); 

    // advance the second result set and print the string it yields 
    rs2.next(); 
    System.out.printf("Result set 2 has '%s'\n", rs2.getString(1)); 

    // close everything up 
    rs2.close(); 
    rs1.close(); 
    cs.close(); 
    conn.close(); 
} 

私はあなたを助けることを願っています!

関連する問題