PLSQL Merge - 在行不存在时更新

时间:2015-04-06 13:57:38

标签: sql oracle merge

我有三个表用户,办公室和角色地图。对于办公室经理和办公室负责人,用户ID将是办公桌的FK。角色和用户ID将映射到角色映射表中,如下所示。 删除办公室后,办公室表的“活动”列将更新为“N”。 当办公室被删除时,我必须检查办公室经理是否担任任何其他办公室的办公室经理。 (同一个人也可以成为另一个市场的经理) 如果不是,那么我必须通过将Active标志更新为'N'<​​/ p>来删除角色映射表中的条目

表用户

User ID | User Name |
--------------------------
1       |   Mark    |

2       |   George  |

3       |   Rick    |

4       |   Alex    |

表办公室

Office ID   | Office Name   | Office Manager| Office Head   |   Active  |
---------------------------------------------------------------------------
1           |   Off1        |   1           |   2           |   Y       |

2           |   Off2        |   1           |   4           |   Y       |

角色地图

User ID |   User Role       |   Active  |
---------------------------------------------
    1   |   Office Manager  |   Y       |

    2   |   Office Head     |   Y       |

    4   |   Office Head     |   Y       |

所以在这个例子中,如果我删除Office 2,那么我需要将角色映射表中的第三个条目更新为以下 OFfice管理员角色映射将保持不变,因为同一用户也是Off1的管理员。

角色地图 - 更新后

User ID |   User Role       |   Active  |
-------------------------------------------
    1   |   Office Manager  |   Y       |

    2   |   Office Head     |   Y       |

    4   |   Office Head     |   N       |

我不确定如何在pl / sql中实现此查询。有人可以指导我吗?

3 个答案:

答案 0 :(得分:2)

我认为在这种情况下不使用merge会更安全。删除办公室或将其状态更新为非活动状态 只需运行此update

update role_map set active = 'N'
  where (user_role = 'Office Head' 
    and not exists (
      select 1 from office 
        where office_head = role_map.user_id and active = 'Y'))
    or (user_role = 'Office Manager' 
    and not exists (
      select 1 from office 
        where office_manager = role_map.user_id and active = 'Y'));

我不确定是否需要表role_map,可能它可以替换为视图,但也许您存储其他一些数据。

答案 1 :(得分:1)

如果您已经从OFFICE表中删除了该行,您只需检查OFFICE表中存在的员工是否具有活动角色,只需执行这样的简单更新 -

UPDATE ROLE_MAP 
   SET active='N' 
 where user_id not in 
    (SELECT office_manager from office
     UNION ALL 
     SELECT office_head from office)

答案 2 :(得分:1)

  

PLSQL Merge - 在行不存在时更新

我认为你不能在 MERGE 声明中使用 WHEN NOT MATCHED 进行 UPDATE

为避免每次删除后都进行手动更新,您可以在office表格上创建 AFTER DELETE触发器,这样每当您删除一行时从office表,更新role_map表。更新语句如下所示:

UPDATE role_map SET active = 'N' WHERE user_id = :OLD.office_head;

例如,只是一个伪代码

CREATE OR REPLACE TRIGGER office_trg
AFTER DELETE
   ON office
   FOR EACH ROW

DECLARE
   -- variable declarations

BEGIN

   -- check any conditions if required

   UPDATE role_map SET active = 'N' WHERE user_id = :OLD.office_head;

EXCEPTION
   WHEN ...
   -- exception handling

END;