You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

批量更新Oracle表时,如何为每行设置不同的随机GUID?

问题描述

需要批量更新Oracle数据库的review_item表多行数据,当前Java代码通过PreparedStatement执行更新,但所有被更新行的target_urn字段都被设置为同一个随机GUID,需求是每行设置不同的随机GUID。当前代码如下:

StringBuilder stringBuilder = new StringBuilder(
          "UPDATE review_item SET LAST_MODIFIED_TIMESTAMP = systimestamp, ")
          .append("target_urn = ?, ")
          .append("assignee_urn = NULL WHERE item_id in (")
          .append(StringUtils.join(itemIds, ","))
          .append(")");

PreparedStatement ps = connection.prepareStatement(stringBuilder.toString());
OracleUtil.bindInput(ps, 1, getRandomUuid(), dbClauses.getQueuePostCleanState());
可行解决方法

方案一:利用Oracle内置函数生成GUID

直接在SQL中使用Oracle自带的SYS_GUID()函数,无需在Java端生成GUID,每行更新时会自动生成唯一值。修改后的代码如下:

StringBuilder stringBuilder = new StringBuilder(
          "UPDATE review_item SET LAST_MODIFIED_TIMESTAMP = systimestamp, ")
          .append("target_urn = SYS_GUID(), ")
          .append("assignee_urn = NULL WHERE item_id in (")
          .append(StringUtils.join(itemIds, ","))
          .append(")");

PreparedStatement ps = connection.prepareStatement(stringBuilder.toString());
ps.executeUpdate();

说明:SYS_GUID()生成的是16字节RAW类型GUID,若target_urn为字符串类型,可改用RAWTOHEX(SYS_GUID())转换为32位十六进制字符串。

方案二:逐行批量更新(适合小数据量场景)

如果必须在Java端生成GUID,可遍历itemIds,为每个ID单独绑定不同的GUID,再批量执行更新:

String sql = "UPDATE review_item SET LAST_MODIFIED_TIMESTAMP = systimestamp, " +
             "target_urn = ?, assignee_urn = NULL WHERE item_id = ?";

try (PreparedStatement ps = connection.prepareStatement(sql)) {
    for (Long itemId : itemIds) {
        String randomUuid = getRandomUuid();
        OracleUtil.bindInput(ps, 1, randomUuid, dbClauses.getQueuePostCleanState());
        ps.setLong(2, itemId);
        ps.addBatch();
    }
    ps.executeBatch();
}

说明:使用addBatch()+executeBatch()批量执行,比循环单条执行效率更高,适合数据量不大的场景。

方案三:临时表关联更新(适合大数据量场景)

针对数据量较大的情况,可先将itemId与对应GUID插入临时表,再通过关联临时表完成批量更新:

  1. 创建临时表(若不存在):
CREATE GLOBAL TEMPORARY TABLE temp_item_guid (
    item_id NUMBER,
    target_urn VARCHAR2(64)
) ON COMMIT DELETE ROWS;
  1. Java代码批量插入数据到临时表:
String insertSql = "INSERT INTO temp_item_guid (item_id, target_urn) VALUES (?, ?)";
try (PreparedStatement insertPs = connection.prepareStatement(insertSql)) {
    for (Long itemId : itemIds) {
        insertPs.setLong(1, itemId);
        insertPs.setString(2, getRandomUuid());
        insertPs.addBatch();
    }
    insertPs.executeBatch();
}
  1. 执行关联更新:
String updateSql = "UPDATE review_item ri " +
                   "SET ri.LAST_MODIFIED_TIMESTAMP = systimestamp, " +
                   "ri.target_urn = tig.target_urn, " +
                   "ri.assignee_urn = NULL " +
                   "WHERE ri.item_id = tig.item_id";

try (PreparedStatement updatePs = connection.prepareStatement(updateSql)) {
    updatePs.executeUpdate();
}

说明:临时表会在事务提交后自动清空数据,这种方式效率远高于逐行更新,适合大规模数据处理。

内容的提问来源于stack exchange,提问作者Mahima Vuppuluri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 19:50:25