Oracle Update Join

时间:2013-10-21 16:02:13

标签: sql oracle

我想通过引用它自己的行中的值以及它在同一个表中的父记录来更新表。

我有一个名为import的表,它需要将子记录的chain_id更新为它的父级的chain_id,如果它当前设置为0而父级不是0.如果动作是3,则将子记录状态设置为1否则保持原样,并将父状态设置为0。

这是一些非工作代码,说明了我正在尝试做的事情:

update 
(
select
c.chain_id as c_chain_id,
c.status as c_status,
c.action as c_action,
p.chain_id as p_chain_id,
p.status as p_status
from import c
join import p on c.original_dissemination_id = p.dissemination_id
where c.chain_id = 0 and
p.chain_id <> 0 and
)
set
c_chain_id = p_chain_id,
c_status = (if c_action = 3 then return 1 else c_status), /* 3 if action = 1 else leave it as it was */
p_status = 0

有人可以将上面的内容翻译成一些有效的oracle代码吗?感谢

2 个答案:

答案 0 :(得分:0)

您是否尝试使用分层查询进行修复?

见这个例子:

   http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm

问候并祝你好运

答案 1 :(得分:0)

我看到的问题是您希望同时进行预制件2更新。实际上,你所拥有的是具有层次关系的两个表c和p。我不知道oracle中只有sql方法一次更新2个表。你可以用视图做一些技巧,可能还有一些非常奇特的SQL。

但是,花哨并不总是最好的解决方案。

我建议使用一些像pl / sql这样的

BEGIN
  FOR v_rec IN (SELECT c.chain_id AS c_chain_id,
                     c.status AS c_status,
                     c.action AS c_action,
                     p.chain_id AS p_chain_id,
                     p.status AS p_status,
                     c.dissemination_id AS c_dissemination_id,
                     p.dissemination_id AS p_dissemination_id
                FROM import c
                JOIN import p ON c.original_dissemination_id = p.dissemination_id
               WHERE c.chain_id = 0
                 AND p.chain_id <> 0) LOOP

    UPDATE import
       SET chain_id = v_rec.p_chain_id,
           status = decode(v_rec.c_action, 3, 1, status)
     WHERE dissemination_id = v_rec.c_dissemination_id;

    UPDATE import
       SET chain_id = 0
     WHERE dissemination_id = v_rec.p_dissemination_id;

    commit;

  END LOOP;

END;
/

这应循环遍历您在上面的查询中定义的所有记录(我添加了我假设的pk和fk列到输出。)这将执行2次更新,解码将处理操作/状态部分。

您当然希望对此进行测试并根据需要进行一些异常处理。