Как проверить все роли, которые не назначены ни одному пользователю, кроме пользователей Oracle по умолчанию (root, system и т. Д.)?

0
задан Rodrigo Farias Rezino 5 March 2019 в 17:16
поделиться

1 ответ

Я понятия не имею, правильны ли ваши запросы 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));

Логика WHERE вашего запроса проверяется один раз для каждой строки в DBA_ROLE_PRIVS, и поэтому GRANTEE всегда будет иметь одно значение - один пользователь. Так что он вернет true только для любого GRANTEE, который входит в ваши VALID_USERS и INVALID_USERS - вероятно, не то, что вы хотите.

Вам необходимо дважды запросить таблицу 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;
0
ответ дан kfinity 5 March 2019 в 17:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: