我在使用 JDBC 时遇到一些结果集问题。
这是我的关系:
create table person (
person_id number(5) generated always as identity
minvalue 1
maxvalue 99999
increment by 1 start with 1
cycle
cache 10,
firstname varchar(10) not null,
lastname varchar(10) not null,
);
我正在尝试在元组中插入一个(名字,姓氏),然后获取从中得出的person_id。这是我的JDBC代码:
//connection is taken care of beforehand and is named con
prep = con.prepareStatement("insert into person (firstname, lastname) values (?, ?)", Statement.RETURN_GENERATED_KEYS);
prep.setString(1, firstname);
prep.setString(2, lastname);
prep.execute();
ResultSet generated = prep.getGeneratedKeys();
if (generated.next()) {
String key = generated.getString("0");
System.out.println(key);
}
这都可以正常工作。但我的问题是键应该是整数,而不是字符串。每次我运行这个,我都会得到一个结果集,其中包含一个字符串"AAA3vaAAGAAAFwbAAG",或者类似的内容。我想获取person_id,以便以后可以在我的 Java 程序中使用它。
在搜索结果集或语句本身的执行方面,我是否做错了什么?
tl;博士
int id = generated.getInt( 1 ) ;
详
你的问题似乎很困惑。
每种get…
方法有两种形式ResultSet
。
- 传递列号(
int
) - 传递列名(
String
)
您似乎已将两者合并为:
字符串键 = 生成.getString( "0" ) ;
我怀疑您有一列以一位数零命名。除了名称选择不当之外,标准 SQL 还禁止以数字开头标识符。
所以这条线毫无意义。也许您使用零0
的意思是第一列,并错误地将其括在引号中,从而将您的预期int
转换为实际String
。
即使是这种意图也是错误的。ResultSet::getString
文档错误地将int
描述为"columnIndex"。通常"索引"是指从零开始的计数偏移量。但实际上ResultSet::getString( int )
要求您传递一个序数,计数从 1 开始。所以getString( 0 )
永远无效。
因此,如果要以文本形式检索结果集第一列的值,请执行以下操作:
String key = generated.getString( 1 ) ; // Retrieve first column of result set as text.
再一次,这在您的代码上下文中是错误的。您显然正在尝试检索INSERT
期间生成的主键值。主键列person_id
定义为非文本类型的number(5)
。因此,作为String
检索是不合适的。
NUMBER(5)
不是标准的 SQL。如果您碰巧使用的是Oracle数据库,则文档说这将是一个精度为五的整数类型,这意味着最多五位数字的数字。因此,通过调用ResultSet::getInt
在 Java 中将其检索为整数类型。
int id = generated.getInt( 1 ) ; // Retrieve the new row’s ID from the first column of the result set of generated key values returned by the `INSERT` prepared statement.
我上面的评论是针对一般数据库的。但特别是对于 Oracle,请参阅Mark Rotteveel的答案,解释Oracle数据库在调用getGeneratedKeys
时不会返回生成的序列号。相反,它返回伪列ROWID
。
您的问题是 Oracle 默认返回插入记录的 ROWID,而不是生成的标识符。摘自 Oracle JDBC 开发人员指南:检索自动生成的密钥:
如果未显式指示键列,则 Oracle JDBC 驱动程序 无法确定需要检索哪些列。当列名 或者使用列索引数组,Oracle JDBC驱动程序可以识别哪个 列包含要检索的自动生成的键。 但是,当
Statement.RETURN_GENERATED_KEYS
整数标志为 使用,Oracle JDBC 驱动程序无法识别这些列。当 整数标志用于指示自动生成的键是 返回时,ROWID
伪列作为键返回。TheROWID
然后可以从ResultSet
对象中获取,并可用于 检索其他列。
因此,如果使用Statement.RETURN_GENERATED_KEYS
,您将获得 ROWID,然后可以使用该 ROWID 选择插入的行以获取其他值(包括生成的标识符)。
如果要专门检索生成的 id,对于 Oracle,您需要显式请求该列,如下所示:
String[] columns = { "PERSON_ID" }
prep = con.prepareStatement(
"insert into person (firstname, lastname) values (?, ?)", columns);
prep.setString(1, firstname);
prep.setString(2, lastname);
prep.executeUpdate();
ResultSet generated = prep.getGeneratedKeys();
if (generated.next()) {
int key = generated.getInt("PERSON_ID");
System.out.println(key);
}