JDBCの自動採番キー機能と、Oracleの拡張SQL文を使用する2パターンの方法がある。
Oracle拡張機能を使用した場合、1レコード更新なら良いが複数レコード更新になると、
クライアント側コードもOracleが拡張したJDBCの機能を使う必要があり、ちと面倒になる。
JDBCの自動採番キー機能
// Statement取得時に、自動採番キーの項目を第二引数で指定する。 // この例では、ID列がシーケンスでの採番対象なので『ID』と指定している。 PreparedStatement statement = con.prepareStatement( "insert into test (ID, NAME) values (TEST_SEQ.nextval, ?)", new String[]{"ID"}); try { statement.setString(1, "hogehoge"); statement.execute(); // SQLを実行後、statementオブジェクトからgetGeneratedKeysを呼び出して、 // 採番キーの結果を取得する。(1行だけなのにResultSetってのが面倒・・・) ResultSet keys = statement.getGeneratedKeys(); try { // ResultSetと同じ感じに値を取得する。 // ただし、カラム名指定でのアクセスは出来ないので、 // インデックス指定でアクセスする必要がある。 keys.next(); int id = keys.getInt(1); System.out.println("id = " + id); } finally { keys.close(); } } finally { statement.close(); } con.commit(); }
Oracleの拡張SQL機能
// Oracleで拡張された、returning intoを使用して、 // IDカラムの値をバインド変数(OUTパラメータに代入する。) // なお、SQL文はbegin endで囲い、無名pl/sqlにする必要がある。 CallableStatement statement = con.prepareCall( "begin insert into test (ID, NAME) " + " values (TEST_SEQ.nextval, ?) returning id into ?; end;"); try { statement.setString(1, "hoge"); // OUTパラメータのタイプを指定する。 statement.registerOutParameter(2, Types.INTEGER); statement.execute(); // SQL実行後に、OUTパラメータの値を取得する。 int id = statement.getInt(2); System.out.println("id = " + id); con.commit(); } finally { statement.close(); }
Oracleの拡張SQL機能で複数行更新の場合
// returning intoを使用してID列をOUTパラメータに代入する。 // SQL文は、通常のSQL文形式で、statementはOracleJDBCのstatementにキャストする。 OracleCallableStatement statement = (OracleCallableStatement) con.prepareCall("update test set id = test_seq.nextval returning id into ?"); try { // registerReturnParameterを呼び出して、データ型を設定する。 // なお、この時に設定するデータ型はOracleTypesがもつ定数を使用する。 statement.registerReturnParameter(1, OracleTypes.INTEGER); int count = statement.executeUpdate(); System.out.println("count = " + count); // getReturnResultSetを呼び出して、OUTパラメータの結果セット(ResultSet)を取得する。 ResultSet set = statement.getReturnResultSet(); try { while (set.next()) { System.out.println("set.getInt(1) = " + set.getInt(1)); } } finally { set.close(); } } finally { statement.close(); }