结果集中的虚假数据



我在使用 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);
}

相关内容

  • 没有找到相关文章

最新更新