一.定义都权限存储过程role无效,必须要显示授权
--建用户并都赋与
DBA权限
create user yx identified by yx
create user jb identified by jb
grant dba to jb
grant dba to yx
--yx创建表
create table yx_tab
as
select * from dba_objects
where rownum<200
--jb用户
sql语句可以正常
select * from yx.yx_tab;
--jb创建存储过程,编译时出错,提示表或视图不存在
CREATE OR REPLACE procedure test
as
begin
delete from yx.yx_tab;
commit;
end;
/
--登录yx用户,显示授权yx_tab表所有权限给jb.再重新编译test存储过程,成功了
grant all on yx_tab to jb
revoke all on yx_tab from jb
二.调用者权限存储过程Role编译不可见,运行可见
CREATE OR REPLACE procedure test(sq varchar2)
AUTHID CURRENT_USER
as
begin
delete from yx.yx_tab;
commit;
end;
/
以上编译时提示表或视图不存在
利用动态SQL避免直接授权,而将权限检查到运行时,以下测试成功
CREATE OR REPLACE procedure test(sq varchar2)
AUTHID CURRENT_USER
as
begin
EXECUTE Immediate 'delete from yx.yx_tab';
commit;
end;
/
三.存储过程中执行DDL操作
存储过程中不能直接执行DDL操作,编译会出错,只能会动态SQL
--登录jb,建立存储过程
CREATE OR REPLACE procedure test(sq varchar2)
as
begin
DBMS_OUTPUT.PUT_LINE (
sq);
EXECUTE Immediate sq;
end;
/
--运行成功
exec test('create table test4(id number)');
--登录yx,执行test后表创建在了用户jb下,而不是yx下
exec jb.test('create table test1(id number)');
--此时需要把test过程改为调用者权限,便可以在当前调用存储过程的用户下创建表
CREATE OR REPLACE procedure test(sq varchar2)
AUTHID CURRENT_USER
as
begin
DBMS_OUTPUT.PUT_LINE (
sq);
EXECUTE Immediate sq;
end;
/
四,通过DBLink调用存储过程
--运行出错,不能通过dblink执行DDL 语句
exec
jb.test@dblink('createtable test1(id number)');
--运行正确,成功删除jb.test1表数据
exec
jb.test@dblink('deletetable jb.test1');
--改写procedure test,加上commit语句
CREATE OR REPLACE procedure test(sq varchar2)
AUTHID CURRENT_USER
as
begin
DBMS_OUTPUT.PUT_LINE (
sq);
EXECUTE Immediate sq;
commit;
end;
/
--执行出错,通过dblink调用的存储过程中不能有commit;
exec
jb.test@dblink('deletetable jb.test1');
该贴由system转至本版2014-11-19 9:35:00