PLSQL 合并 - 在行不存在时更新
PLSQL Merge - Update while row not existing
我有三个 tables User、office 和角色映射。用户 ID 将 FK 到办公室 table 针对办公室经理和办公室主管。角色和用户 ID 将映射到角色映射 table 中,如下所示。
删除办公室后,办公室 table 的活动列将更新为 'N'。
删除办公室后,我必须检查办公室经理是否作为任何其他办公室的办公室经理存在。 (同一个人也可以是另一个市场的经理)
如果他不是,那么我必须通过将 Active 标志更新为 'N'
来删除角色映射 table 中的条目
Table 用户
User ID | User Name |
--------------------------
1 | Mark |
2 | George |
3 | Rick |
4 | Alex |
Table办公室
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,那么我需要将角色映射 table 中的第三个条目更新为以下内容
OOffice 经理角色映射将保持不变,因为同一用户也是 Off1 的经理。
角色地图 -- 更新后
User ID | User Role | Active |
-------------------------------------------
1 | Office Manager | Y |
2 | Office Head | Y |
4 | Office Head | N |
我不确定如何在 pl/sql 中实现此查询。有人可以在这里指导我吗?
如果您已经从 OFFICE table 中删除了该行,您可以只检查 OFFICE table 中存在的员工是否具有活动角色,然后进行简单更新像这样 -
UPDATE ROLE_MAP
SET active='N'
where user_id not in
(SELECT office_manager from office
UNION ALL
SELECT office_head from office)
我认为在这种情况下不使用 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'));
我不确定是否需要table role_map
,也许它可以用视图代替,但也许你存储了一些其他数据。
PLSQL Merge - Update while row not existing
我认为您不能在 MERGE[=26] 中使用 WHEN NOT MATCHED 进行 UPDATE =]声明。
为避免每次删除后都进行手动更新,您可以在 office
上创建一个 AFTER DELETE 触发器 table 这样,每当您从办公室 table 中删除一行时,都会更新 role_map
table。更新语句如下所示:
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;
我有三个 tables User、office 和角色映射。用户 ID 将 FK 到办公室 table 针对办公室经理和办公室主管。角色和用户 ID 将映射到角色映射 table 中,如下所示。 删除办公室后,办公室 table 的活动列将更新为 'N'。 删除办公室后,我必须检查办公室经理是否作为任何其他办公室的办公室经理存在。 (同一个人也可以是另一个市场的经理) 如果他不是,那么我必须通过将 Active 标志更新为 'N'
来删除角色映射 table 中的条目Table 用户
User ID | User Name |
--------------------------
1 | Mark |
2 | George |
3 | Rick |
4 | Alex |
Table办公室
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,那么我需要将角色映射 table 中的第三个条目更新为以下内容 OOffice 经理角色映射将保持不变,因为同一用户也是 Off1 的经理。
角色地图 -- 更新后
User ID | User Role | Active |
-------------------------------------------
1 | Office Manager | Y |
2 | Office Head | Y |
4 | Office Head | N |
我不确定如何在 pl/sql 中实现此查询。有人可以在这里指导我吗?
如果您已经从 OFFICE table 中删除了该行,您可以只检查 OFFICE table 中存在的员工是否具有活动角色,然后进行简单更新像这样 -
UPDATE ROLE_MAP
SET active='N'
where user_id not in
(SELECT office_manager from office
UNION ALL
SELECT office_head from office)
我认为在这种情况下不使用 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'));
我不确定是否需要table role_map
,也许它可以用视图代替,但也许你存储了一些其他数据。
PLSQL Merge - Update while row not existing
我认为您不能在 MERGE[=26] 中使用 WHEN NOT MATCHED 进行 UPDATE =]声明。
为避免每次删除后都进行手动更新,您可以在 office
上创建一个 AFTER DELETE 触发器 table 这样,每当您从办公室 table 中删除一行时,都会更新 role_map
table。更新语句如下所示:
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;