我尝试为现有表中的每一行生成一个uuid,并为两个不同的列设置相同的值。
我写了一个update语句,我认为应该这样做,但它为每一列设置了一个 * 不同的 * uuid。为什么?
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;
N | RAWTOHEX(R1) | RAWTOHEX(R2) |
---|---|---|
1 | F89B6F66D7C7A52FE050020A02583951 | F89B6F66D7C8A52FE050020A02583951 |
二 | F89B6F66D7C9A52FE050020A02583951 | F89B6F66D7CAA52FE050020A02583951 |
三 | F89B6F66D7CBA52FE050020A02583951 | F89B6F66D7CCA52FE050020A02583951 |
2条答案
按热度按时间dgiusagp1#
这与this question和this question的问题相同,因为
SYS_GUID
函数调用没有在子查询中具体化,而是被推送到update语句并每行调用两次(每列一次);但是,这些问题的答案并不完全适用于UPDATE
语句。相反,您可以使用
MERGE
语句:在
MERGE
之后,您的示例数据可能包含:| N|RAWTOHEX(R1)|RAWTOHEX(R2)|
| --------------|--------------|--------------|
| 1|F89CAC01141C1982E053182BA8C018B2|F89CAC01141C1982E053182BA8C018B2|
| 二|F89CAC01141D1982E053182BA8C018B2|F89CAC01141D1982E053182BA8C018B2|
| 三|F89CAC01141E1982E053182BA8C018B2|F89CAC01141E1982E053182BA8C018B2|
另一种方法是使用两个
UPDATE
语句:fiddle
ep6jt1vc2#
如前所述,这是因为Oracle不存储计算值,而是将原始表达式传播到外部查询。而在
join
的情况下,它不会这样做。为了避免在
merge
期间进行连接,您可以使用update
的(column [, column ]...) = (subquery)
分支,根据需要使用left join
到dual
生成尽可能多的相同计算值。UPD。上面的文本中有一个错误,因为我在子查询中丢失了一个强制逐行执行的相关性。所以代码被更新了。
您也可以将
rownum
添加到set ... = (subquery)
中的子查询中,而不是join
。fiddle