无法使用 PreparedStatement 的 getGeneratedKeys() 在 Java 中找到生成的密钥
Posted
技术标签:
【中文标题】无法使用 PreparedStatement 的 getGeneratedKeys() 在 Java 中找到生成的密钥【英文标题】:Unable to find a generated key in Java using PreparedStatement's getGeneratedKeys() 【发布时间】:2012-04-17 10:23:11 【问题描述】:我有一个查询如下:
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(); 有一些东西 这让我很困惑。
我做错了什么?
提前致谢
【问题讨论】:
您没有使用“生成的密钥”,您只是在 INSERT 语句中使用了生成器。getGeneratedKeys()
用于返回由数据库生成的键,作为 INSERT 的一部分(通过标识列或通过触发器)。
【参考方案1】:
我希望您返回的看起来像字符串的“键”是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 ?";
【讨论】:
谢谢。我选择了您的第一个选项来包含 generateColumns。事实上,我的 ResultSet 首先给了我一些我不理解的行,但现在我传递 string[] "id" 返回新生成的 id。【参考方案2】:如果这不起作用,则问题可能出在 sequence.nextval 上。如果您正在使用它,您似乎并没有在技术上自动生成密钥
【讨论】:
【参考方案3】:我很确定getGeneratedKeys
不会返回使用序列的下一个值初始化的键的值。实际上,在这种情况下,数据库不会自己生成密钥(就像使用自动增量列一样)。
如果你想知道生成的密钥,那么执行第一个查询:
select sequence.nextval from dual
然后使用第一个查询的结果来执行你准备好的语句:
insert into table (id, name) values (?, ?)
【讨论】:
【参考方案4】:我认为:
pStatement.setString('blabla');
应该是:
pStatement.setString(1, 'blabla');
希望对你有帮助。
【讨论】:
对不起 - 你是对的。这是我的错,因为我没有在此处复制粘贴我的代码,而是尝试以更一般的术语键入示例以使代码更易于阅读。但是,在我的代码中,我做得正确。所以虽然你是对的,但这不是我正在努力解决的问题。我已经编辑了我的帖子。 @arnehehe 你是对的,你可以编译你的代码,所以这不是错误。我的错。【参考方案5】:您的代码有一个错误:由于您使用的是 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.
【讨论】:
以上是关于无法使用 PreparedStatement 的 getGeneratedKeys() 在 Java 中找到生成的密钥的主要内容,如果未能解决你的问题,请参考以下文章
即使明确设置 PreparedStatement 也不会超时