项目里出现了一个问题,在外服进行了合服操作之后,创建角色的存储过程调用失败了。
具体的失败原因是因为存储过程执行权限限制,
继续查证,发现权限认证的用户IP为被合并服务器的IP,
嗯……合服之后,我们回收了这个IP对数据库的访问权限。。
那么理一下出问题的流程:
1.存储过程是在被合并服务器上进行创建的,因此存储过程的创建者指定为该IP用户
2.存储过程执行权限检测默认为检测创建者权限(DR)
3.创建者没有了权限,导致调用失败
先解决问题:
1.先恢复该IP的权限
2.改代码,将存储过程权限设置为调用者权限,在CREATE PROCEDURE proname(...)后紧跟权限设置语句:SQL SECURITY INVOKER
然后学习一下这两种权限是怎么一回事:
DR Procedure:DR是Definer's Rights,创建者权限,名称解析环境为定义该过程用户所在的Schema
IR Procedure:IR是Invoker's Rights,调用者权限,名称解析环境为调用该过程用户所在的Schema
用户一 Mem_One 创建了删除表tar_table的存储过程drop_table(),调用drop_table()的时候,删除了用户Mem_One下的表tar_table;
用户二 Mem_Two调用drop_table(),是删除哪一个用户下的表?若drop_table()中还有建表语句,还要考虑Public没有建表权限的问题,除非为Public grant建表权限;
也就是说 存储过程的调用者面临两个问题:
1.存储过程的名称解析环境
2.存储过程的执行权限
这两个问题可以在定义存储过程的时候,通过指定AUTHID属性,即定义DR Procedure和IR Procedure来解决
比如:指定当前调用者权限:
CREATE OR REPLACE procedure DEMO(ID in NUMBER) AUTHID CURRENT_USER as
...
BEGIN
...
END DEMO;
这里的 AUTHID CURRENT_USER就是使用调用者的权限,相对应的是:AUTHID DEFINER,使用创建者权限,
我们还可以使用另一种指定:
在CREATE语句后面跟:SQL SECURITY INVOKER,相对应的是:SQL SECURITY DEFINER