ORACLE SQL:相关更新问题

时间:2014-04-16 08:59:17

标签: oracle sql-update correlated

大家好,我有关于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:单行子查询返回多行'

如何使此更新有效?

2 个答案:

答案 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_pid_s的主组合的结果集与根据排名的相同列的从组合的结果集配对按顺序排列。排序只是根据列valuedesc的结果集的顺序,但当然任何其他排序也会这样做(请注意,特别是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_pid_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;