0

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

我怎样才能使这个更新工作?

4

2 回答 2

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与相同列的从属组合的结果集按照 2 次排序的排名配对。排序只是根据列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 上进行了测试。

于 2014-04-16T10:37:00.137 回答
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;
于 2014-04-16T11:04:41.467 回答