1

我从http://docs.oracle.com/javase/1.4.2/docs/guide/jdbc/getstart/preparedstatement.html获得了以下代码示例

我有三个问题:

  1. 考虑到只有三列 - LAST、FIRST、HOME,'keyColumn' 指的是什么。
  2. 为什么在迭代生成的密钥时使用循环?是否为该一个插入语句返回了多行?
  3. 哪些数据库支持每个表生成多个键?
String sql = "INSERT INTO AUTHORS (LAST, FIRST, HOME) VALUES " +
                                     "(?, ?, ?, keyColumn)";

PreparedStatement addAuthor = con.prepareStatement(sql,
                             Statement.RETURN_GENERATED_KEYS);
addAuthor.setString(1, "Wordsworth");
addAuthor.setString(2, "William");
addAuthor.setString(3, "England");

int rows = addAuthor.executeUpdate();

ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()) {
    ResultSetMetaData rsmd = rs.getMetaData();
    int colCount = rsmd.getColumnCount();
    do {
        for (int i = 1; i <= colCount; i++) {
            String key = rs.getString(i);
            System.out.println("key " + i + "is " + key);
        }
    }
    while (rs.next();)
} 
else {
    System.out.println("There are no generated keys.");
}
4

1 回答 1

3

问题1。我认为keyColumn在您的链接查询中只是示例中的错误。该段中的第二个和第三个示例也包含严重的语法错误。我不会详述它。该文档已从较新的 Java 版本中完全删除。

问题 2. 考虑类似INSERT INTO ... SELECT ... FROM ...orINSERT INTO ... VALUES (...), (...)可以产生多个插入行的语句。此外,一些数据库支持从其他 DML(例如UPDATEor DELETE)返回值,这也会影响多行,这就是您需要考虑循环的原因。在此特定示例中,没有必要,因为您可以确定只会插入一行。

问题 3. 这个问题有点复杂:

一些数据库(或驱动程序)不能轻易确定实际生成的列是什么。例如因为数据库没有IDENTITY列,而是使用触发器来生成键。识别生成的键将涉及解析表上的所有触发器以检查它是否将生成的值分配给(主键或其他)列,这不容易完成并且容易出错。有时会生成多个列(即计算字段等)。作为开发人员,您应该知道您可以或想要返回哪些字段。

由于很难(或低效)决定返回哪些字段,一些驱动程序(默认情况下)返回插入(或删除/更新)行的所有列。例如 PostgreSQL 和 Firebird 驱动程序就是这样做的。另一方面,即使表不包含标识列,一些驱动程序也只会返回最后生成的键(我相信 MySQL 会,但不是 100% 肯定)。而且我似乎记得 Oracle 驱动程序只是返回ROWID,让用户使用它从数据库中检索实际值ROWID

如果您明确知道要返回哪些列,则可以使用接受列序索引列名数组的替代方法指定自己。尽管并非所有驱动程序都支持这一点。

于 2012-11-03T10:00:49.397 回答