我有一个已经很复杂的SQL语句,它创建了一个拥有权限CONNECT
,APPUSER
或两者的用户表:
(SELECT b.grantee AS "Username", A.granted_role AS "Connect", b.granted_role AS "APPUSER" FROM
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'CONNECT') A
RIGHT OUTER JOIN
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'APPUSER') b
ON A.grantee=b.grantee)
UNION
(SELECT A.grantee, A.granted_role, b.granted_role FROM
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'CONNECT') A
LEFT OUTER JOIN
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'APPUSER') b
ON A.grantee=b.grantee)
这会产生类似:
Username Connect APPUSER
--------- --------- ---------
Sue CONNECT APPUSER
Bob (null) APPUSER
Joe CONNECT (null)
我希望使用all_users
表来显示既没有权限的用户。 all_users
表显示数据库中的每个用户。
我尝试在SQL语句的末尾添加几种类型的连接来实现此目的。我得到的最接近的是:
UNION
(SELECT username, NULL, NULL FROM all_users)
这将生成一个列表,其中每个用户显示两次,但显示没有正确的用户:
Username Connect APPUSER
--------- --------- ---------
Amy (null) (null)
Sue CONNECT APPUSER
Sue (null) (null)
Bob (null) APPUSER
Bob (null) (null)
Joe CONNECT (null)
Joe (null) (null)
我尝试添加where username = a.grantee
,但这对联盟不起作用。如果我尝试将UNION
替换为任何JOIN
,例如添加:
FULL OUTER JOIN
SELECT username, NULL, NULL FROM ALL_USERS
on username = a.grantee;
我收到错误:
“SQL命令未正确结束”
答案 0 :(得分:2)
您的查询似乎比必要的更复杂。这是一种方法:
select grantee,
max(case when granted_role = 'CONNECT' then granted_role end) as "connect",
max(case when granted_role = 'APPUSER' then granted_role end) as "appuser"
from dba_role_privs
group by grantee;
如果有用户完全没有角色,那么您将需要all_users
表。
编辑:
只需使用left join
:
select au.userName,
max(case when granted_role = 'CONNECT' then granted_role end) as "connect",
max(case when granted_role = 'APPUSER' then granted_role end) as "appuser"
from all_users au join
dba_role_privs rp
on au.userName = rp.grantee
group by au.userName;
答案 1 :(得分:1)
我不太确定我理解第一个查询。当你可以使用PIVOT时,你似乎正在做一些非常复杂的事情。但是,如果它正常工作,那么你应该能够做到:
SELECT username
FROM ALL_USERS
WHERE username NOT IN (
(SELECT DISTINCT b.grantee AS "Username", A.granted_role AS "Connect", b.granted_role AS "APPUSER" FROM
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'CONNECT') A
RIGHT OUTER JOIN
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'APPUSER') b
ON A.grantee=b.grantee)
UNION
(SELECT A.grantee, A.granted_role, b.granted_role FROM
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'CONNECT') A
LEFT OUTER JOIN
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'APPUSER') b
ON A.grantee=b.grantee)
)
答案 2 :(得分:1)
使用以下查询。让我知道这个是否奏效。你需要在where子句中添加dp1.granted_role为null并且dp2.granted_role为null。
select au.username,
dp1.granted_role,
dp2.granted_role
from all_users au
left join dba_role_privs drp1 on drp1.grantee=au.username and drp1.granted_role='CONNECT'
left join dba_role_privs drp2 on drp2.grantee=au.username and drp2.granted_role='APPUSER'