oracle - 使用过程但不使用 plsql 块创建 Oracle 序列时获得足够的权限
问题描述
Begin
Execute immediate 'CREATE SEQUENCE seq1 MINVALUE 1 MAXVALUE 99 START WITH 1INCREMENT BY 1 CACHE 20';
End;
Sequence creating successfully.
Create or replace procedure proc_seq as
Begin
Execute immediate 'CREATE SEQUENCE seq2 MINVALUE 1 MAXVALUE 99 START WITH 1INCREMENT BY 1 CACHE 20';
End;
Exec proc_seq();
Error: Insufficient Privilege...
解决方案
这是一个调用者/定义者权利问题。默认情况下,存储过程具有定义者的权利(DR - 强调添加):
在服务器调用期间,当 DR 单元被推入调用堆栈时,数据库存储当前启用的角色以及 和 的当前
CURRENT_USER
值CURRENT_SCHEMA
。然后它将 CURRENT_USER 和 CURRENT_SCHEMA 都更改为 DR 单元的所有者,并仅启用角色PUBLIC
。
如果通过角色授予您创建序列的权限,则由于该角色将被禁用,因此该权限无效。您可以通过运行来验证情况是否如此set role none
,这将导致您的匿名块失败并出现相同的错误。
正如@Littlefoot 所说,您可以将特权直接授予您,而不是(或同时)通过角色。
或者,您可以指定该过程应具有调用者的权限:
Create or replace procedure proc_seq
authid current_user
as
Begin
Execute immediate 'CREATE SEQUENCE seq2 MINVALUE 1 MAXVALUE 99 START WITH 1INCREMENT BY 1 CACHE 20';
End;
/
exec proc_seq;
PL/SQL procedure successfully completed.
select seq2.nextval from dual;
NEXTVAL
----------
1
希望这是一个人为的例子;无论如何,您通常不会在运行时创建数据库对象...
这种方法的警告是它可能不适合您打算如何调用该过程。如果您以自己的身份运行它,那很好,但如果您将授予其他用户执行权限,那么他们将必须拥有相关权限(直接授予或通过角色授予);并将在自己的模式中创建对象。这可能正是您想要的。但如果不是,并且您不想授予create sequence
调用者或让他们创建自己的对象,那么您可以保留具有定义者权限的过程并直接将权限授予您的用户。
推荐阅读
- mongodb - 如何使用 MongoDB 聚合的结果?
- powershell - 是否可以将 Send-MailMessage 与默认凭据一起使用?
- mysql - 使用 Scala 从一个平台查询另一个平台
- python - 我如何计算我在递归中划分了多少次?
- java - Android Studio:内存不足:Java 堆空间
- mysql - 为什么在这种情况下最好不要打破每列存储多个值的标准化 N1 规则?
- javascript - 触摸板镀铬窗口上的溢出-x
- javascript - jQuery:获取像检查这样的元素而不是源代码
- postman - 我只想在运行的第一次迭代期间执行集合中的特定文件夹。这可能吗?
- xcode - Xcode 11 在当前呈现的屏幕后面显示所有屏幕