AUTHID的使用
默认情况下,存储过程和sql方法的执行是以其拥有者的权限,而不是当前用户权限。
不需要查询名字,即可调用拥有者用户下的其他程序。
例如scott和blake都有一个dept表,scott拥有的过程可以通过dept直接访问,而不用scott.dept。
如果用户blake调用scott的存储过程,存储过程中调用的是scott用户下的表,而不是blake用户的。
实验:
1.不加authid的效果
(1)scott用户下创建存储过程insert_emp:
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
Connected as scott
SQL> CREATE OR REPLACE PROCEDURE insert_emp
2 IS
3 BEGIN
4 INSERT INTO emp VALUES ('8000','TL','MANAGER','','','','','10');
5 commit;
6 END;
7 /
Procedure created
(2)创建blake用户,并授予其对scott用户insert_emp的all权限:
PL/SQL procedure successfully completed
SQL> create user blake identified by blake;
User created
SQL> grant all on p_test to blake;
Grant succeeded
注:这步操作是在scott用户下执行的,如果scott没有创建用户的权限,需要到sys等用户下创建(或授予scott创建用户权限)
此外,还需要给blake用户connect和resource权限:
SQL> grant connect to blake;
Grant succeeded
SQL> grant resource to blake;
Grant succeeded
(3)在scott用户下查看emp表
SQL> select * from emp where empno='8000';
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
//无返回结果
(4)查看blake的权限:
SQL> conn blake/blake@testdb_192.168.56.130
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
Connected as blake
SQL> select * from user_sys_privs;
USERNAME PRIVILEGE ADMIN_OPTION
------------------------------ ---------------------------------------- ------------
BLAKE UNLIMITED TABLESPACE NO
SQL> select * from user_tab_privs;
GRANTEE OWNER TABLE_NAME GRANTOR PRIVILEGE GRANTABLE HIERARCHY
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------------------------------------- --------- ---------
BLAKE SCOTT P_TEST SCOTT DEBUG NO NO
BLAKE SCOTT P_TEST SCOTT EXECUTE NO NO
SQL> select * from user_role_privs;
USERNAME GRANTED_ROLE ADMIN_OPTION DEFAULT_ROLE OS_GRANTED
------------------------------ ------------------------------ ------------ ------------ ----------
BLAKE CONNECT NO YES NO
BLAKE RESOURCE NO YES NO
PUBLIC PLUSTRACE NO YES NO
(5)blake用户执行scott的insert_emp存储过程
SQL> set serveroutput on;
SQL> exec scott.insert_emp;
PL/SQL procedure successfully completed
(6)scott用户下查看效果:
SQL> conn scott/scott@testdb_192.168.56.130
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
Connected as scott
SQL> select * from emp where empno='8000';
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
8000 TL MANAGER 10
2.添加authid
(1)scott用户下修改存储过程:
SQL> conn scott/scott@testdb_192.168.56.130
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
Connected as scott
SQL> CREATE OR REPLACE PROCEDURE insert_emp
2 AUTHID CURRENT_USER
3 IS
4 BEGIN
5 INSERT INTO emp VALUES ('9999','TL','MANAGER','','','','','10');
6 commit;
7 END;
8 /
Procedure created
//在原来的基础上添加authid current_user,并修改了插入的记录
(2)blake用户下新建表emp:
SQL> conn scott/scott@testdb_192.168.56.130
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
Connected as scott
SQL> grant select on emp to blake;
Grant succeeded
SQL> conn blake/blake@testdb_192.168.56.130
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
Connected as blake
SQL> drop table emp;
Table dropped
SQL> creat table emp as select * from scott.emp where 1=2;
Table created
(3)执行存储过程,查看结果
SQL> exec scott.insert_emp;
PL/SQL procedure successfully completed
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
9999 TL MANAGER 10
3.错误
(1)在scott用户下将emp表改名:
SQL> alter table emp rename to emp11;
Table altered
(2)在blake用户下执行存储过程:
SQL> exec scott.insert_emp;
begin scott.insert_emp; end;
ORA-06550: ? 1 ?, ? 13 ?:
PLS-00905: ?? SCOTT.INSERT_EMP ??
ORA-06550: ? 1 ?, ? 7 ?:
PL/SQL: Statement ignored
小结:以上现象就比较明显了。
1)我们在scott用户下创建存储过程,未指明schema的情况下,调用的都是scott用户下的对象(表)
2)当我们在其他schema下调用scott的这个存储过程时,仍然会在scott用户下寻找对象,而不是去其他用户下寻找。
3)使用authid子句进行身份说明后,在其他用户下调用scott下的存储过程,会对访问者的对象进行操作
4)步骤3中出现的问题是由于scott中不存在emp表,导致存储过程编译不通过,其他用户无法调用
·························································
如果我们要在A用户下调用B用户下的存储过程,而需要存储过程中对A中的对象(表)进行操作(查找),有两种方法
1)在存储过程中使用schema.object_name的方式完成调用,并赋予B用户对相应对象的权限
2)使用authid,指明从A中获取对象
authid有两个取值,CURRENT_USER表示当前的调用用户;DEFINER表示存储过程所在用户,和不加authid子句效果相同。
题外话(关于权限)
1)scott用户不需要有对blake用户下emp表的任何权限
2)如果给blake用户scott.emp的select权限,该表执行alter table emp rename to emp_11;后,blake有对emp_11的select权限。但drop后再重建同名表,则没有权限
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26451536/viewspace-748791/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/26451536/viewspace-748791/