如何检查未分配给任何用户但oracle默认用户(root,system等)的所有角色?

时间:2019-03-05 17:16:11

标签: sql oracle

我正在尝试创建一个SQL,以获取所有未由任何自定义(非默认)oracle用户使用的角色,或由处于无效状态的用户使用的所有角色。 对我来说,无效状态意味着以SRV_%开头且其状态不同于OPEN的用户。

到目前为止,我拥有的sql是这样的:

with
  INVALID_USERS as
    (
      select
        USERNAME
      from
        DBA_USERS
      where
        USERNAME like 'SRV_%'
        and ACCOUNT_STATUS != 'OPEN'
    ),
  VALID_USERS as (
    select
      USERNAME
    from
      DBA_USERS
    where
      USERNAME not like 'SRV_%'
      and (not ACCOUNT_STATUS = 'LOCKED')
  )
select *
from
  DBA_ROLE_PRIVS drolp
  join DBA_ROLES drol ON drol.ROLE = drolp.GRANTED_ROLE
where
  GRANTEE in (select USERNAME from INVALID_USERS)
  and GRANTEE not in (select USERNAME from VALID_USERS);

可能我需要使用HAVING从无效用户角色使用中删除有效用户的出现。 我被困在那里。

1 个答案:

答案 0 :(得分:0)

我不知道您的VALID_USER和INVALID_USER查询是否正确,因为您尚未向我们提出要求。但是我认为这是您的主要查询的问题:

with
  INVALID_USERS as
    (
      select
        USERNAME
      from
        DBA_USERS
      where
        USERNAME like 'SRV_%'
        and ACCOUNT_STATUS != 'OPEN'
    ),
  VALID_USERS as (
    select
      USERNAME
    from
      DBA_USERS
    where
      USERNAME not like 'SRV_%'
      and (not ACCOUNT_STATUS = 'LOCKED')
  )
select *
from
  DBA_ROLES drol
where
  -- role is assigned to AT LEAST ONE "invalid user"
  EXISTS (select 1 from DBA_ROLE_PRIVS drolp where drol.ROLE = drolp.GRANTED_ROLE and GRANTEE in (select USERNAME from INVALID_USERS))
  -- and role is not assigned to ANY "valid users"
  and NOT EXISTS (select 1 from DBA_ROLE_PRIVS drolp where drol.ROLE = drolp.GRANTED_ROLE and GRANTEE in (select USERNAME from VALID_USERS));

对于DBA_ROLE_PRIVS中的每一行,都会查询一次查询的WHERE逻辑,因此GRANTEE将始终是一个值-一个用户。因此,它仅对您VALID_USERS和INVALID_USERS中的任何GRANTEE返回true -可能不是您想要的。

您需要查询DBA_ROLE_PRIVS表两次-一次检查有效用户,一次检查无效用户。您可以使用聚合函数解决该问题,尽管您必须将条件置于GROUP BY之外-将其设置为子查询或将其移动到类似这样的HAVING子句中:

with
  INVALID_USERS as
    (
      select
        USERNAME
      from
        DBA_USERS
      where
        USERNAME like 'SRV_%'
        and ACCOUNT_STATUS != 'OPEN'
    ),
  VALID_USERS as (
    select
      USERNAME
    from
      DBA_USERS
    where
      USERNAME not like 'SRV_%'
      and (not ACCOUNT_STATUS = 'LOCKED')
  )
select GRANTED_ROLE
from
  DBA_ROLE_PRIVS drolp
  join DBA_ROLES drol on drol.ROLE = drolp.GRANTED_ROLE
group by GRANTED_ROLE
having
  -- role is assigned to AT LEAST ONE "invalid user"
  sum(CASE when GRANTEE in (select USERNAME from INVALID_USERS) THEN 1 else 0 end) > 0
  -- and role is not assigned to ANY "valid users"
  and sum(CASE when GRANTEE in (select USERNAME from VALID_USERS) THEN 1 else 0 end) = 0;