繁体   English   中英

插入时返回序列号

[英]Return sequence number on insert

通过OrderDAO对象将订单插入HSQL数据库后,我希望能够检索在插入时分配给订单的序列号。

我有这个用于我的PreparedStatement

public long saveOrder(Order order) {
    long orderId = 0;
    try (Connection conn = MyDataSource.getDataSource().getConnection();
         PreparedStatement ps = conn.prepareStatement("INSERT INTO orders(id, order_number) VALUES (NEXT VALUE FOR seq1, ?)",
                                                            PreparedStatement.RETURN_GENERATED_KEYS)) {

        ps.setString(1, order.getOrderNumber());
        ps.execute();

        ResultSet rs = ps.getResultSet();
        if (rs.next()) {
            orderId = rs.getLong(1);
        }

    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    return orderId;
}

我假设在执行查询并询问其结果集之后,结果集中的第一列将是序列号。 但是看来我不是那样工作的。

我在哪里错呢?

您的代码有两个问题:

  1. 您使用错误的方法来检索生成的键结果集。 只能使用getGeneratedKeys() (或至少是JDBC规范要求的)来检索生成的键结果集。

    您需要更改代码以使用ps.getGeneratedKeys()而不是ps.getResultSet()

  2. 另一个问题是您的代码采用非标准的生成键行为:您的插入实际上并没有使用JDBC规范意图的生成键,因为您自己在insert语句中生成标识符(使用NEXT VALUE FOR seq1 ),而不是将密钥作为插入语句的副作用生成(例如,通过标识列或触发器)。

    HSQLDB在这种情况下不会返回生成的键,因为它不将id视为生成的列。 相反,您需要将该列定义为一个标识列(并且不要在插入中显式指定它),或者替代地,显式指定要返回的列。

    有关创建标识列的信息,请参考HSQLDB文档。 明确指定要返回的列

     conn.prepareStatement("<query>", PreparedStatement.RETURN_GENERATED_KEYS) 

    与任一列的索引规范返回(即1是第一列):

     conn.prepareStatement("<query>", new int[] { 1 }) 

    或要返回的列的列名说明

     conn.prepareStatement("<query>", new String[] { "id" }) 

您的最终代码应类似于:

try (PreparedStatement ps = conn.prepareStatement(
         "INSERT INTO orders(id, order_number) VALUES (NEXT VALUE FOR seq1, ?)",
         new String[] { "id" })) {
    ps.setString(1, order.getOrderNumber());
    ps.execute();

    try (ResultSet rs = stmt.getGeneratedKeys()) {
        if (rs.next()) {
            return rs.getLong(1);
        }
    }
}

基于此SO问答 ,您的语法应如下所示:

Connection conn = MyDataSource.getDataSource().getConnection();
long orderId = 0;
String sql = "INSERT INTO orders (id, order_number) VALUES (NEXT VALUE FOR seq1, ?)";
PreparedStatement ps = conn.prepareStatement(sql, RETURN_GENERATED_KEYS);
ps.setString(1, order.getOrderNumber());
int numAffected = ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next()) {
    orderId = rs.getLong(1);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM