我有以下代码:
List<List<Object>> batch = db.executeInsert("insert into Batches (batch_date,source,log_file,status) values (?, ?, ?, ?)",
now,
importZip.getAbsolutePath(),
logFile.getAbsolutePath(),
BatchStatus.IMPORTING.toString())
当我在MySQL上运行它时返回的数据返回一个Integer,表示插入的ID符合预期。在Oracle下运行时,它返回一个不可移植的ROWID
对象。我有一个标识列,最终将转换为表示ID的序列。但是,使用ROWID
无法解决问题。
我已经检查了代码,我正在调用statement.getGeneratedKeys()
,我认为这是制作可移植代码的重点。如何在不执行明显不可移植的select from table where ROWID=?
之类的情况下以便携方式编写此内容。
答案 0 :(得分:1)
正如您已经发现的那样,Oracle返回ROWID
,以便您可以 - 例如 - 通过查询行来获取id。
有些数据库只返回最后生成的id(可能甚至不属于表,例如MySQL AFAIK),有些数据库只返回id列作为ResultSet
中的第一列,其他数据库返回所有列(例如PostgreSQL,Firebird默认情况下),因此id列的位置可能不一定是第一列,因为它取决于表中的列顺序。
唯一真正的选择是创建一个特定于数据库的策略,该策略知道获取正确列的规则。这可能涉及触发针对Oracle的额外查询,使用一些启发式方法来查找PostgreSQL和Firebird的主键列等。
答案 1 :(得分:1)
所以我找到的便携式解决方案是使用稍微不同的PreparedStatement版本和getGeneratedKeys()。结果是在mysql和oracle上都是可移植的,我想象其他人:
Connection connection = createConnection();
PreparedStatement statement = null;
statement = connection.prepareStatement(sql,new String[] { "ID" });
int updateCount = statement.executeUpdate();
ResultSet keysRs = statement.getGeneratedKeys();
if( keysRs.next() ) {
return keyRs.getInteger("ID");
}
这是我使用的解决方案。