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

Oracle异常行为:使用sys_guid()更新时两列UUID不同的原因

问题:UPDATE语句中两列UUID值不同的原因及解决办法

我想给现有表的每一行生成一个UUID,让两个不同列(r1、r2)的值相同,但执行自己写的UPDATE语句后,每列的UUID却不一样,这是为什么?

用到的SQL代码如下:

CREATE TABLE tbl (
    n number,
    r1 raw(32),
    r2 raw(32)
);

insert into tbl (n) values (1);
insert into tbl (n) values (2);
insert into tbl (n) values (3);

update (select r1, r2, sys_guid() as uuid FROM tbl) 
    set r1 = uuid, r2 = uuid;
    
select n, rawtohex(r1), rawtohex(r2) from tbl;

查询结果显示每行的r1和r2UUID不同:

NRAWTOHEX(R1)RAWTOHEX(R2)
1F89B6F66D7C7A52FE050020A02583951F89B6F66D7C8A52FE050020A02583951
2F89B6F66D7C9A52FE050020A02583951F89B6F66D7CAA52FE050020A02583951
3F89B6F66D7CBA52FE050020A02583951F89B6F66D7CCA52FE050020A02583951

原因分析

核心问题是Oracle中SYS_GUID()函数的执行时机:
你在子查询里定义了uuid别名,但Oracle并不会将这个值缓存下来复用。当执行set r1 = uuid, r2 = uuid时,每一次引用uuid都会重新调用SYS_GUID()生成新值,所以r1和r2会得到不同的UUID。


解决办法

以下几种写法都能实现每行生成一个UUID并同步到两列:

方法1:用关联子查询更新

先通过子查询为每行生成唯一UUID,再关联原表批量更新:

UPDATE tbl t
SET (t.r1, t.r2) = (
    SELECT s.uuid, s.uuid
    FROM (SELECT n, SYS_GUID() AS uuid FROM tbl) s
    WHERE s.n = t.n
);

方法2:使用MERGE语句

MERGE的逻辑更清晰,先预先生成每行的UUID,再匹配更新:

MERGE INTO tbl t
USING (SELECT n, SYS_GUID() AS uuid FROM tbl) s
ON (t.n = s.n)
WHEN MATCHED THEN
    UPDATE SET t.r1 = s.uuid, t.r2 = s.uuid;

方法3:PL/SQL循环(适合小表)

通过PL/SQL变量缓存UUID,确保每行只生成一次:

DECLARE
    v_uuid RAW(32);
BEGIN
    FOR rec IN (SELECT n FROM tbl) LOOP
        v_uuid := SYS_GUID();
        UPDATE tbl SET r1 = v_uuid, r2 = v_uuid WHERE n = rec.n;
    END LOOP;
    COMMIT;
END;
/

执行以上任意一种方法后,再查询表数据,每行的r1和r2就会拥有相同的UUID值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 11:42:23