Java準備済みステートメントでクエリを使用するときに、DBクエリから自動生成キーを取得する方法はありますか。
たとえば、AutoGeneratedKeysは次のように機能します。
stmt = conn.createStatement();
stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
if(returnLastInsertId) {
ResultSet rs = stmt.getGeneratedKeys();
rs.next();
auto_id = rs.getInt(1);
}
しかしながら。準備されたステートメントで挿入を行いたい場合はどうなりますか。
String sql = "INSERT INTO table (column1, column2) values(?, ?)";
stmt = conn.prepareStatement(sql);
//this is an error
stmt.executeUpdate(Statement.RETURN_GENERATED_KEYS);
if(returnLastInsertId) {
//this is an error since the above is an error
ResultSet rs = stmt.getGeneratedKeys();
rs.next();
auto_id = rs.getInt(1);
}
私が知らないこれを行う方法はありますか。 javadocから、PreparedStatementsは自動生成IDを返すことができないようです。
はい。 here を参照してください。セクション7.1.9。コードを次のように変更します。
String sql = "INSERT INTO table (column1, column2) values(?, ?)";
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
stmt.executeUpdate();
if(returnLastInsertId) {
ResultSet rs = stmt.getGeneratedKeys();
rs.next();
auto_id = rs.getInt(1);
}
いくつかの方法があり、異なるjdbcドライバーが少し異なることを処理するようです、またはまったくない場合もあります(一部は自動生成された主キーのみを提供し、他の列は提供しません)が、基本的な形式は
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
または、このフォームを使用します。
String autogenColumns[] = {"column1","column2"};
stmt = conn.prepareStatement(sql, autogenColumns)
はい、方法があります。 Java doc。
彼らの方法は、次のようにAutoGeneratedKeys IDを渡すことです
String sql = "INSERT INTO table (column1, column2) values(?, ?)";
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
私は、この問題の解決策を探しているいくつかのスレッドをサーフィンして、最終的に機能するようになった人の1人です。 jdbc:Oracle:thin:with ojdbc6.jarを使用する場合注:いずれかの方法を使用できます:(方法1)
Try{
String yourSQL="insert into Table1(Id,Col2,Col3) values(SEQ.nextval,?,?)";
myPrepStatement = <Connection>.prepareStatement(yourSQL, Statement.RETURN_GENERATED_KEYS);
myPrepStatement.setInt(1, 123);
myPrepStatement.setInt(2, 123);
myPrepStatement.executeUpdate();
ResultSet rs = getGeneratedKeys;
if(rs.next()) {
Java.sql.RowId rid=rs.getRowId(1);
//what you get is only a RowId ref, try make use of it anyway U could think of
System.out.println(rid);
}
} catch (SQLException e) {
//
}
(方法2)
Try{
String yourSQL="insert into Table1(Id,Col2,Col3) values(SEQ.nextval,?,?)";
//IMPORTANT: here's where other threads don tell U, you need to list ALL cols
//mentioned in your query in the array
myPrepStatement = <Connection>.prepareStatement(yourSQL, new String[]{"Id","Col2","Col3"});
myPrepStatement.setInt(1, 123);
myPrepStatement.setInt(2, 123);
myPrepStatement.executeUpdate();
ResultSet rs = getGeneratedKeys;
if(rs.next()) {
//In this exp, the autoKey val is in 1st col
int id=rs.getLong(1);
//now this's a real value of col Id
System.out.println(id);
}
} catch (SQLException e) {
//
}
基本的に、SEQ.Nextvalの値だけが必要な場合はMethod1を使用しないでください。RowIDrefを返すだけなので、それを使用する方法を見つけるために頭を割ることができます。それに!これは、MySQL、DB2では正常に機能する(実際のvalを返す)場合がありますが、Oracleでは機能しません。
また、デバッグ時に、SQL Developer、Toad、または同じログインセッションを使用してINSERTを実行するクライアントをオフにします。毎回(デバッグコール)影響しない場合があります...しばらく例外なくアプリがフリーズするまで。はい...例外なく停止します!