WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606
全部博文(599)
分类: Oracle
2011-11-03 11:07:00
http://yangtingkun.itpub.net/post/468/272716
今天在处理一个JOB错误的时候,才发现自己对JOB的运气权限理解有误。
一直认为JOB中WHAT存放的是匿名块,因此JOB中使用的权限应该和匿名块一致。没有想到JOB相当于定义者权限存储过程中的权限,只对直接授权有效,而对角色无效。
看一个简单的例子:
SQL> CREATE TABLE T (ID NUMBER);
表已创建。
SQL> CREATE USER TEST IDENTIFIED BY TEST DEFAULT TABLESPACE YANGTK;
用户已创建
SQL> GRANT CONNECT, RESOURCE TO TEST;
授权成功。
SQL> CREATE ROLE R_INSERT_T;
角色已创建
SQL> GRANT INSERT ON T TO R_INSERT_T;
授权成功。
SQL> GRANT R_INSERT_T TO TEST;
授权成功。
SQL> CONN TEST/TEST@TEST
已连接。
SQL> INSERT INTO YANGTK.T VALUES (1);
已创建 1 行。
SQL> BEGIN
2 INSERT INTO YANGTK.T VALUES (2);
3 END;
4 /
PL/SQL 过程已成功完成。
SQL> CREATE OR REPLACE PROCEDURE P_TEST_DEFINE AS
2 BEGIN
3 EXECUTE IMMEDIATE 'INSERT INTO YANGTK.T VALUES (3)';
4 END;
5 /
过程已创建。
SQL> EXEC P_TEST_DEFINE
BEGIN P_TEST_DEFINE; END;
*
ERROR 位于第 1 行:
ORA-00942: 表或视图不存在
ORA-06512: 在"TEST.P_TEST_DEFINE", line 3
ORA-06512: 在line 1
通过角色获得的授权,可以在SQL中和匿名块中使用,但是对定义者存储过程无效。
下面看看JOB的情况:
SQL> DECLARE
2 V_JOB NUMBER;
3 BEGIN
4 DBMS_JOB.SUBMIT(V_JOB, 'BEGIN INSERT INTO YANGTK.T VALUES (5); END;', SYSDATE);
5 COMMIT;
6 END;
7 /
PL/SQL 过程已成功完成。
SQL> COL WHAT FORMAT A60
SQL> SELECT JOB, WHAT, FAILURES FROM USER_JOBS;
JOB WHAT FAILURES
---------- ---------------------------------------------------- ----------
104 BEGIN INSERT INTO YANGTK.T VALUES (5); END; 1
SQL> EXEC DBMS_JOB.RUN(104)
BEGIN DBMS_JOB.RUN(104); END;
*
ERROR 位于第 1 行:
ORA-12011: 无法执行 1 作业
ORA-06512: 在"SYS.DBMS_IJOB", line 406
ORA-06512: 在"SYS.DBMS_JOB", line 272
ORA-06512: 在line 1
显然JOB无法正常运行,检查后台ALERT文件:
Sun Mar 18 20:35:49 2007
Errors in file f:oracleadmintestudumptest_ora_1032.trc:
ORA-12012: 自动执行作业 104 出错
ORA-06550: 第 1 行, 第 121 列:
PL/SQL: ORA-00942: 表或视图不存在
ORA-06550: 第 1 行, 第 102 列:
PL/SQL: SQL Statement ignored
由此可见,JOB的权限和存储过程一致,通过角色的授权是无效的。
SQL> CONN YANGTK/YANGTK@TEST
已连接。
SQL> GRANT INSERT ON T TO TEST;
授权成功。
SQL> CONN TEST/TEST@TEST
已连接。
SQL> EXEC DBMS_JOB.RUN(104)
PL/SQL 过程已成功完成。