当使用带有预准备语句的java查询时,是否有办法从数据库查询中检索自动生成的密钥。
例如,我知道AutoGeneratedKeys可以如下工作。
stmt = conn.createStatement();
stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
if(returnLastInsertId) {
ResultSet rs = stmt.getGeneratedKeys();
rs.next();
auto_id = rs.getInt(1);
}
然而。如果我想使用准备好的Statement进行插入,该怎么办?
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。
答案 0 :(得分:91)
是。见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);
}
答案 1 :(得分:3)
有几种方法,似乎不同的jdbc驱动程序处理的东西有点不同,或者在某些情况下根本不处理(有些只会给你自动生成的主键,而不是其他列)但是基本形式是
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
或使用此表格:
String autogenColumns[] = {"column1","column2"};
stmt = conn.prepareStatement(sql, autogenColumns)
答案 2 :(得分:2)
是的,有办法。我刚刚发现这隐藏在java doc中。
他们的方式是传递AutoGeneratedKeys id,如下所示
String sql = "INSERT INTO table (column1, column2) values(?, ?)";
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
答案 3 :(得分:2)
我是那些通过几个线程寻找解决这个问题的人之一...并最终让它发挥作用。对于那些使用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,b'cse它只返回RowID引用,你可能会破解你的头部找到使用它的方法,这也适合所有数据类型你试过把它投到了!这可能在MySQL,DB2中正常工作(返回实际的val),但在Oracle中却没有。
AND,关闭您的SQL Developer,Toad或任何使用相同登录会话的客户端在您调试时执行INSERT。它可能不会影响你每次(调试调用)...直到你发现你的应用程序冻结一段时间没有异常。是的......毫无例外地停止!
答案 4 :(得分:-1)
Connection connection=null;
int generatedkey=0;
PreparedStatement pstmt=connection.prepareStatement("Your insert query");
ResultSet rs=pstmt.getGeneratedKeys();
if (rs.next()) {
generatedkey=rs.getInt(1);
System.out.println("Auto Generated Primary Key " + generatedkey);
}