执行PL / SQL块时,将忽略授予角色的任何权限。相反,您必须为特定用户提供特定授权才能运行它。如果我想让DBA访问包或函数或过程,我不能给DBA角色一个授权。我必须向DBA角色中的每个用户授予一个授权,如果他们不再是DBA,我必须删除用户的授权,并且我必须将授权添加到任何新的DBA。
我发现这很难维护。
我的问题是为什么PL / SQL以这种方式工作? Oracle决定这是Roles和PL / SQL应该如何协同工作的设计考虑因素?我一直无法找到一个不是“那就是它的方式”的答案。
答案 0 :(得分:2)
它可能是懒惰和SET ROLE
命令的组合。
我不同意因为复杂的依赖关系而不允许这样做。 Oracle已经管理了复杂的依赖项。在12c中,可以为对象授予角色。
我认为对象不能继承用户角色的真正原因是SET ROLE
命令。可以为用户分配角色,但在会话中打开和关闭它。这是一个愚蠢的功能,我从来没有见过它。但从理论上讲,它需要在同一个会话或事务中重新编译,这实在令人困惑。
答案 1 :(得分:1)
也许我在这里没有正确理解某些东西,因为我做了你说不能做的事情。事实上,Oracle文档说它可以完成。请查看this document中有关过程安全性的部分。 (@ ibre5041)由于程序在所有者的特权下运行,因此无需重新编译任何内容。仅检查用户(或他的角色)权限是否允许他们运行该过程。 我错过了什么?
答案 2 :(得分:1)
否则,如果删除某个角色,则PL / SQL包在某些情况下将变为INVALID(无需重新编译)。
DROP ROLE ...
是DCL(数据控制语言)语句。看起来Oracle决定:“PL / SQL包不会被DCL语句变为无效”
答案 3 :(得分:0)
我认为这是一些历史遗产。在更改ROLE的对象权限时,Oracle会重新编译大量的PL / SQL存储代码。 PS:你也可以创建名为" SCHEMA"。
的东西请参阅CREATE SCHEMA声明。
答案 4 :(得分:0)
我认为您可能会争夺Invokers权利与Definers权利。
来自Oracle docs:
在服务器调用期间,当DR单元被推入调用堆栈时, 数据库存储当前启用的角色和当前值 CURRENT_USER和CURRENT_SCHEMA。然后它会更改CURRENT_USER 和CURRENT_SCHEMA到DR单元的所有者,并仅启用 角色PUBLIC 。 (存储的和新的角色和值不一定 不同的。)当DR单元从调用堆栈弹出时, 数据库恢复存储的角色和值。相反,当一个IR 单元被推入或弹出调用堆栈,其值为 CURRENT_USER和CURRENT_SCHEMA,以及当前启用的角色 不要改变
因此,如果您希望Oracle尊重角色"授予的权限,那么您可能希望使用Invokers权限(AUTHID CURRENT_USER子句)