为模式中的角色重新生成GRANT

Dav*_*vis 7 sql oracle roles grant

此问题类似,我想知道如何生成GRANT发布给一组模式中的所有角色的所有语句以及名称以"PROXY"结尾的角色列表.我想重新创建如下语句:

GRANT SELECT ON TABLE_NAME TO ROLE_NAME;
GRANT EXECUTE ON PACKAGE_NAME TO ROLE_NAME;
Run Code Online (Sandbox Code Playgroud)

目的是帮助从开发数据库迁移到测试数据库(Oracle 11g).有些工具会尝试自动执行此操作,但通常会失败.

有任何想法吗?

APC*_*APC 9

此脚本生成授予角色的所有表权限的列表...

select 'grant '||privilege||' on '||owner||'.'||table_name||' to '||grantee
         ||case when grantable = 'YES' then ' with grant option' else null end
         ||';'
from dba_tab_privs
where owner in ('A', 'B')
and grantee in ( select role from dba_roles )
order by grantee, owner
/
Run Code Online (Sandbox Code Playgroud)

请注意,我不限制被授予者角色,因为您的问题在这一点上含糊不清.您可能需要在sub_query上添加过滤器dba_roles.如果你有授予其他角色的角色,你也会想要选择那些角色......

select 'grant '||granted_role||' to '||grantee
         ||case when admin_option = 'YES' then ' with admin option' else null end
         ||';'
from dba_role_privs
where grantee in ( select role from dba_roles )
order by grantee, granted_role
/
Run Code Online (Sandbox Code Playgroud)

获取角色列表......

select 'create role '||role ||';'
from dba_roles
where role like '%PROXY'
/
Run Code Online (Sandbox Code Playgroud)

请注意,这些脚本不会为系统特权生成授权.此外,如果使用目录对象,生活会稍微复杂一些,因为这需要一个额外的关键词......

select 'grant '||privilege||' on '||owner||'.'||table_name||' to '||grantee
         ||case when grantable = 'YES' then ' with grant option' else null end
         ||';'
from dba_tab_privs
where owner in ('A', 'B')
and grantee in ( select role from dba_roles )
and table_name not in ( select directory_name from dba_directories )
union all
select 'grant '||privilege||' on directory '||table_name||' to '||grantee
         ||case when grantable = 'YES' then ' with grant option' else null end
         ||';'
from dba_tab_privs
where grantee in ( select role from dba_roles )
and table_name  in ( select directory_name from dba_directories )
/
Run Code Online (Sandbox Code Playgroud)

编辑

在9i中,Oracle引入了DBMS_METADATA包,它在一个简单的PL/SQL API中包含了很多这类查询.例如,此调用将生成具有授予A的所有对象权限的CLOB ...

select dbms_metadata.get_granted_ddl('OBJECT_GRANT', 'A') from dual
/
Run Code Online (Sandbox Code Playgroud)

这显然比滚动我们自己简单得多.