今天介绍一下关于定义者权限和执行者权限的一些知识内容。

PL/SQL的程序、函数、包有“定义者权限”或“执行者权限”两种权限的区别。默认为“定义权限”。

“定义者权限”(默认)的定义的存储过程,不管是哪个用户去执行那个存储过程,都会在“定义者的权限和模式”中执行的(即与执行者无关)。
例如,SCOTT数据库用户有一个PROC1程序程序,这个程序对EMP表和EMP表进行SELECT查询。
下边是具体的例子内容,因为这个过程没有做任何特殊的设置,所以这个存储过程默认的是“定义者权限”。

–例子开始–

SQL> CREATE OR REPLACE PROCEDURE PROC1
 2 IS
 3 V_ENAME VARCHAR2(20);
 4 BEGIN
 5 SELECT ENAME INTO V_ENAME FROM EMP WHERE EMPNO = 7934;
 6 DBMS_OUTPUT.PUT_LINE(V_ENAME);
 7 END;
 8 /

程序已创建。

–例子结束—

这个程序功能:表示员工编号(EMPNO)是7934的员工的名字(ENAME)。

实行结果如下:
SQL>SET SERVEROUT ON --SQLPlus(SQLDeveloper)的画面输出有效
SQL>SHOW USER --查看当前用户
用户是“SCOTT”。 --当前用户为SCOTT用户

SQL>EXEC PROC1 --执行PROC1过程
MILLER

PL/SQL过程成功完成。

在上面的例子中,PROC1属于用户SCOTT,从PROC1程序的执行结果可以看出,在SCOTT用户的EMP表中,员工编号7934的员工名是大写字母“MILLER”。

假如有如下场景:
用“ALLEN”用户,该ALLEN用户也有与SCOTT用户相同的EMP表。 但是,ALLEN用户的EMP表中,7934的员工的名字是小写的 “milller”。

SQL> SHOW USER
用户是“ALLEN”。–当前用户为ALLEN用户

–根据SCOTT的EMP表制作同一名称的表
SQL> CREATE TABLE EMP AS SELECT * FROM SCOTT.EMP;

表创建成功。

–员工编号7934的员工名为小写“miler”
SQL> UPDATE EMP SET ENAME = ‘miller’ WHERE EMPNO = 7934

一行已更新。

SQL>COMMIT;–提交

提交完成。

SQL> SELECT ENAME FROM EMP WHERE EMPNO = 7934;
ENAME
----------
milller --员工7934是小写字母“milller”

假如用ALLEN用户执行SCOTT用户的PROC1过程(前提:SCOTT用户的PROC1的执行被授权给用户ALLEN),结果会怎么样呢?
查询ALLEN的EMP表,会显示小写字母“milller”吗?还是大写的呢?

我们试试看:

SQL> CONNECT SCOTT/tiger
已连接。

SQL> SHOW USER
用户是“SCOTT”。–现在是SCOTT用户

–吧SCOTT的PROC1程序的执行权限授予给ALLEN用户
SQL> GRANT EXECUTE ON SCOTT.PROC1 TO ALLEN;

授权成功。

SQL> CONNECT ALLEN/allen
已连接。
SQL> SHOW USER
用户是“ALLEN”。–成为ALLEN用户
SQL> SET SERVEROUTPUT ON
SQL> SELECT ENAME FROM EMP WHERE EMPNO = 7934;

ENAME

miler - -ALLEN的EMP表中,员工7934的名字是小写的“miler”

SQL> SET SERVEROUTPUT ON
SQL> EXEC SCOTT.PROC1
MILLER --但是,过程的结果是大写字母“MILLER”

PL/SQL过程成功完成。

通过结果,我们可以知道程序中查询的不是ALLEN的EMP表,而是SCOTT的EMP表。

如上所述,即使用用户ALLEN执行,这个程序查询的是作为存储过程定义者的SCOTT的EMP表。这就是所谓的存储过程的“定义者权限”的概念。

也就是说,这个PROC1过程中记述的“EMP”表,无论那个用户去执行这个过程,都是“定义者SCOTT的EMP”表。也就是说,这是在“定义者模式”中执行的。

aaaaaaaaa’

那么,ALLEN通过这个程序,SELECT SCOTT的EMP表,不过,ALLENSCOTT.EMP的SELECT权限。

但是不是问题。执行者只要有执行那个程序的权限就可以,其中进行的各个操作是由定义者的权限进行的,所以执行者不需要这些权限。

所以,“定义者权限”的存储过程无论那个用去执行,都会以“定义者的权限和模式”来执行。

假如我们想要通过用户ALLEN执行SCOTT.PROC1,想要查询ALLEN的EMP表而不是SCOTT的EMP表,该怎么办呢?也就是怎样才能显示小写字母“miler”呢?

答案是:需要把SCOTT.PROC1,变更为“执行者权限”就可以了。

那么,那个方法下次说明。敬请期待。