Oracle中如何打乱TESTE2表CPF列并更新,解决ORA-30926错误
解决Oracle中打乱列数据并更新表的ORA-30926错误
错误原因
你遇到的ORA-30926: unable to get a stable set of rows in the source tables错误,是因为MERGE语句中使用ON (1=1)作为匹配条件,Oracle无法在源表和目标表之间建立稳定的行对应关系。加上DBMS_RANDOM.VALUE会导致源表的随机序号每次计算都变化,进一步加剧了匹配的不稳定性。
正确解决方案
要实现打乱CPF列并更新全表,需要给原表的每行分配固定的唯一序号,同时给打乱后的CPF数据分配对应的随机序号,通过序号建立稳定的关联后再执行更新。
方法1:使用MERGE语句
MERGE INTO danilo.teste2 t1 USING ( -- 给原表每行分配固定序号(基于rowid,确保唯一且稳定) SELECT t.rowid AS row_id, ROW_NUMBER() OVER (ORDER BY t.rowid) AS seq_num FROM danilo.teste2 t ) original_data ON (t1.rowid = original_data.row_id) -- 关联打乱后的CPF数据,按序号匹配 JOIN ( SELECT cpf, ROW_NUMBER() OVER (ORDER BY DBMS_RANDOM.VALUE) AS seq_num FROM danilo.teste2 ) shuffled_cpf ON original_data.seq_num = shuffled_cpf.seq_num WHEN MATCHED THEN UPDATE SET t1.cpf = shuffled_cpf.cpf;
方法2:使用UPDATE语句
UPDATE danilo.teste2 t1 SET cpf = ( SELECT sc.cpf FROM ( -- 生成带随机序号的打乱CPF列表 SELECT cpf, ROW_NUMBER() OVER (ORDER BY DBMS_RANDOM.VALUE) AS seq_num FROM danilo.teste2 ) sc JOIN ( -- 给原表每行分配固定序号 SELECT rowid, ROW_NUMBER() OVER (ORDER BY rowid) AS seq_num FROM danilo.teste2 ) od ON sc.seq_num = od.seq_num WHERE od.rowid = t1.rowid );
说明
- 使用
rowid作为原表行的唯一标识是因为它是Oracle中每行的物理唯一标识,不会随数据变化而改变,确保序号分配稳定。如果你的表有主键,也可以用主键代替rowid来生成固定序号。 - 两种方法都会将原表的CPF值随机重新分配给每行,实现你需要的“掩码”效果,同时所有CPF都是原表中存在的真实数据。
内容的提问来源于stack exchange,提问作者Astora
相关产品推荐
相关产品推荐

