使用PreparedStatement的getGeneratedKeys()无法在Java中找到生成的密钥

时间:2012-04-03 18:01:16

标签: java sql oracle prepared-statement auto-increment

我的查询如下:

String SQL = "insert into table (id, name) values (sequence.nextval, ?)";

然后我制作一个像这样的PreparedStatement:

//initiate connection, statement etc
pStatement = connection.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS);
pStatement.setString(1,'blabla');

pStatement.executeUpdate();
ResultSet rs = pStatement.getGeneratedKeys();

while (rs.next()){
  //debugging here to see what rs has
}

在该调试点执行和调试时,我看到我的ResultSet只有一个键,一个字符串 - 与我期望的id不同。检查数据库时一切正常,id插入和一切。有一些关于 getGeneratedKeys(); 的内容 那令我困惑。

我做错了什么?

提前致谢

5 个答案:

答案 0 :(得分:10)

我希望你回来的那个看起来像字符串的“密钥”是ROWID - 这是数据库直接生成的唯一密钥。您应该能够更改它以获取id列(这可能需要适度的最新版本的JDBC驱动程序)。

//initiate connection, statement etc
String generatedColumns[] = {"ID"};
pStatement = connection.prepareStatement(SQL, generatedColumns);
pStatement.setString(1,'blabla');

pStatement.executeUpdate();
ResultSet rs = pStatement.getGeneratedKeys();

while (rs.next()){
  //debugging here to see what rs has
}

您还可以更改查询以显式添加RETURNING子句

String SQL = "insert into table (id, name) " + 
             "  values (sequence.nextval, ?) " + 
             "  returning id into ?";

答案 1 :(得分:1)

如果这不起作用,问题可能在于sequence.nextval。看起来如果你正在使用它,你在技术上并不是自动生成密钥

答案 2 :(得分:1)

我很确定getGeneratedKeys不会返回使用序列的下一个值初始化的键的值。实际上,在这种情况下,数据库本身不会生成密钥(就像使用自动增量列一样)。

如果您想知道生成的密钥,请执行第一个查询:

select sequence.nextval from dual

然后使用第一个查询的结果来执行您准备好的语句:

insert into table (id, name) values (?, ?)

答案 3 :(得分:1)

我想这个:

pStatement.setString('blabla');

应该是:

pStatement.setString(1, 'blabla');

希望它有所帮助。

答案 4 :(得分:0)

您的代码有错误:由于您使用的是PreparedStatement,因此您应该使用自己的RETURN_GENERATED_KEYS常量:

pStatement = connection.prepareStatement(SQL, PreparedStatement.RETURN_GENERATED_KEYS);

getGeneratedKeys()函数应该没有问题地执行,你应该能够获得ResultSet变量中生成的密钥。

通过这种方式,您不需要为您的行指定任何名称(正如Justin解决方案所暗示的那样,这非常好)。如果使用以下方法访问检索到的密钥,则只需指定行名称:

id = rs.getInt("id_row_name");

而不是:

id = rs.getInt(column_number); //One column for each key retrieved.