大家好,我有关于oracle相关更新的这类问题。
考虑我有一张表参数。
id_s id_p value desc
-----------------------------------------------
10064 9 aaa r
10064 8 bbb t
10064 4 ccc t
10064 4 ttt y
11119 9 ddd f
11119 8 eee g
11119 4 fff b
11119 4 kkk x
所以我想更新参数以获取以下内容
id_s id_p value desc
-----------------------------------------------
10064 9 aaa r
10064 8 bbb t
10064 4 ccc t
10064 4 ttt y
11119 9 aaa r
11119 8 bbb t
11119 4 ccc t
11119 4 ttt y
我写这样的更新
update params p1
set (p1.value, p1.desc) = (
select p2.value
, p2.desc
from params p2
where p2.id_s = 10064
and p2.id_p = p1.id_p
)
where p1.id_s = 11119
;
执行返回错误' ORA01427:单行子查询返回多行'
如何使此更新有效?
答案 0 :(得分:0)
您必须在子查询中添加其他条件:
update params p1
set (p1.value, p1.desc) = (
select p2.value
, p2.desc
from params p2
where p2.id_s = 10064
and p2.id_p = p1.id_p
and p1.id_s = 11119
)
where p1.id_s = 11119
;
修改强> 操作规范的更新使事情变得更加复杂,这实际上相当于部分pk更新(只要表格摘录在列中完整)。
一个可能的解决方案实现了以下基本思想:id_p
,id_s
的主组合的结果集与根据排名的相同列的从组合的结果集配对按顺序排列。排序只是根据列value
和desc
的结果集的顺序,但当然任何其他排序也会这样做(请注意,特别是2 不同的排序是可行的。)
然后将所述配对与更新结果集相关联。
在oracle sql中:
update params p1
set (p1.value, p1.desc) = (
select emb.value
, emb.desc
from (
select p2.value
, p2.desc
, p2.id_p
, rownum rn
from params p2
where p2.id_s = 10064
order by p2.value
, p2.desc
) emb
join (
select pm.value
, pm.desc
, pm.id_p
, rownum rn
from params pm
where pm.id_s = 11119
order by pm.value
, pm.desc
) emb_master
ON ( emb_master.id_p = emb.id_p
AND emb_master.rn = emb.rn )
where p1.id_s = 11119
and emb_master.id_p = p1.id_p
and emb_master.value = p1.value
and emb_master.desc = p1.desc
)
where p1.id_s = 11119
;
该方案的可行性取决于假设结果集模块化元组的每个值(id_p
,id_s
)具有相同的可能性。如果你没有,那么更新将是不完整的。
根据给出的摘录在ora 11g2上进行测试。
答案 1 :(得分:0)
当返回多行时,您不指定要执行的操作。您只需使用rownum = 1
选择任意行:
update params p1
set (p1.value, p1.desc) = (
select p2.value, p2.desc
from params p2
where p2.id_s = 10064 and p2.id_p = p1.id_p and rownum = 1
)
where p1.id_s = 11119;