2009-03-25 11 views
5

へのJDBC接続を使用してINSERT文から私はこの仕事を行う権利魔法の組み合わせを得るように見えることはできません。リターンROWIDパラメータオラクル


OracleDataSource ods = new oracle.jdbc.pool.OracleDataSource(); 
ods.setURL("jdbc:oracle:thin:app_user/[email protected]:1521:sid"); 
DefaultContext conn = ods.getConnection(); 
CallableStatement st = conn.prepareCall("INSERT INTO tableA (some_id) VALUES (1) RETURNING ROWID INTO :rowid0"); 
st.registerReturnParameter(1, OracleTypes.ROWID); 
st.execute(); 

私が手にエラーが「プロトコル違反」です。私がregisterOutParameter()に変更すると、すべての戻り変数を登録していないことが通知されます。 PL/SQLで文をラップする場合終わり;ブロックすると、通常のregisterOutParameter()呼び出しを使用してパラメータを正常に取得できます。 PL/SQLですべてのINSERTステートメントをラップすることを避けることを本当に好むでしょう - 上に欠けているのは何ですか?

答えて

6

OracleTypesの:あなたはすなわち、試してみて、NUMBERへ戻るOracleCallableStatementを

    • 変更のCallableStatementを行う必要がありますいくつかのこと。クエリからの情報を返すための番号

    サンプルコード:OracleのJDBC拡張の

    OraclePreparedStatement pstmt = (OraclePreparedStatement)conn.prepareStatement(
         "delete from tab1 where age < ? returning name into ?"); 
    pstmt.setInt(1,18); 
    
    /** register returned parameter 
        * in this case the maximum size of name is 100 chars 
        */ 
    pstmt.registerReturnParameter(2, OracleTypes.VARCHAR, 100); 
    
    // process the DML returning statement 
    count = pstmt.executeUpdate(); 
    if (count>0) 
    { 
        ResultSet rset = pstmt.getReturnResultSet(); //rest is not null and not empty 
        while(rset.next()) 
        { 
        String name = rset.getString(1); 
        ... 
        } 
    } 
    

    さらに詳しい情報:

  • +0

    [@kaidoは、データベースにとらわれない最適なソリューションを提供しています。](http://stackoverflow.com/questions/682539/return-rowid-parameter-from- insert-statement-using-jdbc-connection-oracle/881414#881414)。 –

    1

    をお試しください。 の代わりに:SQL文字列にrowid0を追加してください。以前は名前付きのパラメータとOracleで問題がありました。

    3

    使用しているバージョンを指定していないため、これが適用されるかどうかわかりません。 Oracleのメタリンクから

    :10.1.0.x JDBCドライバで

    原因

    、DMLを返すことはサポートされていません。JDBCよくある質問パー

    : 「10.1.0( 10g r1) DMLリターンがサポートされていますか? 現在のドライバには含まれていませんが、10.1.0以降のドライバでサポートする計画があります。 は実際にこの時点を意味します。

    アプリケーションコードがサポートされていないJDBC機能を使用しようとすると、エラーが発生します。

    「10.2.0(10グラムのR2:よくある質問ごと10.2.0.x JDBCドライバがRETURNING句をサポートしていないため

    ソリューション

    、10.2.0.xへJDBCドライバをアップグレード) はYES ?DMLはサポートされて戻っている!そして、それは時間についてです。詳細については、開発者ガイドを参照してください。」

    EDIT ただにやにや笑いのために、あなたは、JDBCのOracleのバージョンを確認することができますそれはで使用しています考えて:...それはJDBCドライバ10.2.0.xを示して以降、私はアイデアの出だと、おそらくOracleへのサポート要求が順番になっている場合

    // Create Oracle DatabaseMetaData object 
        DatabaseMetaData meta = conn.getMetaData(); 
    
        // gets driver info: 
        System.out.println("JDBC driver version is " + meta.getDriverVersion()); 
    

    +0

    おかげで、ここでは、私が使用しています様々なバージョンは次のとおりです。 1.6.0_12-b04 仮想マシンのバージョン:11.2-b01(HotSpot Server) Oracle Server: 10.2.0.4 Oracleクライアント:11.1.0.7.0からojdbc6.jar – Goyuix

    15

    通常、あなたがしたくありませんコードデータベースを依存させる。 OraclePreparedStatementではなく、CallableStatementを使用する必要があります。

    CallableStatement statement = connection.prepareCall("{call INSERT INTO tableA (some_id) VALUES (1) RETURNING ROWID INTO ? }"); 
    statement.registerOutParameter(1, Types.VARCHAR); 
    
    int updateCount = statement.executeUpdate(); 
    if (updateCount > 0) { 
        return statement.getString(1); 
    } 
    
    +1

    この構文的な砂糖はまさに私が必要としていたものです - {call} –

    +0

    私の一日を保存、ありがとう!!! – Gaucho

    +0

    私にも働きました。注意すべき点は、INパラメータとOUTパラメータがある場合、常にインデックスが上がることです。だから '{INSERT INTO tbl(x、y)VALUES(seq.NEXTVAL、?)RETURNING x INTO? } '' seq.NEXTVAL'は 'getLong(1)'ではなく 'statement.getLong(2)'に返されます。 – 0xbe5077ed

    1
    PreparedStatement prepareStatement = connection.prepareStatement("insert...", 
          new String[] { "your_primary_key_column_name" }); 
    
        prepareStatement.executeUpdate(); 
    
        ResultSet generatedKeys = prepareStatement.getGeneratedKeys(); 
        if (null != generatedKeys && generatedKeys.next()) { 
         Long primaryKey = generatedKeys.getLong(1); 
        } 
    

    私は、これは完璧に動作している答えを発見しました。私はJAVAから挿入して、そのキーと共に返すことができます。

    フルバージョン:

    CREATE TABLE STUDENTS 
    (
        STUDENT_ID NUMBER NOT NULL PRIMARY KEY, 
        NAME   VARCHAR2 (50 BYTE), 
        EMAIL  VARCHAR2 (50 BYTE), 
        BIRTH_DATE DATE 
    ); 
    
    
    CREATE SEQUENCE STUDENT_SEQ 
        START WITH 0 
        MAXVALUE 9999999999999999999999999999 
        MINVALUE 0; 
    

    とJavaコード

    String QUERY = "INSERT INTO students "+ 
           " VALUES (student_seq.NEXTVAL,"+ 
           "   'Harry', '[email protected]', '31-July-1980')"; 
    
    // load oracle driver 
    Class.forName("oracle.jdbc.driver.OracleDriver"); 
    
    // get database connection from connection string 
    Connection connection = DriverManager.getConnection(
         "jdbc:oracle:thin:@localhost:1521:sample", "scott", "tiger"); 
    
    // prepare statement to execute insert query 
    // note the 2nd argument passed to prepareStatement() method 
    // pass name of primary key column, in this case student_id is 
    // generated from sequence 
    PreparedStatement ps = connection.prepareStatement(QUERY, 
         new String[] { "student_id" }); 
    
    // local variable to hold auto generated student id 
    Long studentId = null; 
    
    // execute the insert statement, if success get the primary key value 
    if (ps.executeUpdate() > 0) { 
    
        // getGeneratedKeys() returns result set of keys that were auto 
        // generated 
        // in our case student_id column 
        ResultSet generatedKeys = ps.getGeneratedKeys(); 
    
        // if resultset has data, get the primary key value 
        // of last inserted record 
        if (null != generatedKeys && generatedKeys.next()) { 
    
         // voila! we got student id which was generated from sequence 
         studentId = generatedKeys.getLong(1); 
        } 
    
    } 
    

    ソース: Javaのバージョン:情報のためhttp://viralpatel.net/blogs/oracle-java-jdbc-get-primary-key-insert-sql/