我在 USER A 中有一个对象,用于更新 USER B 架构中的表。运行包时,它使用 USER B 的登录名在 Oracle 中运行。
用户 A 没有更新用户 B 模式中的表的权限。当我尝试在 USER A 的架构中编译包时,我收到权限不足的错误消息,导致它无法编译。
有没有办法在 USER A 的模式中编译一个对象,即使他没有更新 USER B 的表的权限?如果包在 USER B 的上下文中运行,包会正确更新表吗?
我不想将包放入 USER B 的架构中。
你可以。但这可能不是最好的方法。该包需要被声明为调用者的权限包。并且该UPDATE
语句需要使用动态 SQL。
在中创建表B
SQL> create table b.foo( col1 number );
Table created.
SQL> insert into b.foo values( 1 );
1 row created.
SQL> commit;
Commit complete.
在 中创建包A
。请注意,声明了包,authid current_user
这意味着它依赖于调用用户的权限,而不是定义用户的权限。由于A
看不到表,我们使用动态 SQL,以便将语法检查推迟到运行时
SQL> create package update_foo
2 authid current_user
3 as
4 procedure set_val( p_new_val in number );
5 end;
6 /
Package created.
SQL> ed
Wrote file afiedt.buf
1 create or replace package body update_foo
2 as
3 procedure set_val( p_new_val in number )
4 as
5 begin
6 execute immediate 'update b.foo set col1 = :new_val'
7 using p_new_val;
8 end;
9* end;
SQL> /
Package body created.
SQL> grant execute on update_foo to b;
Grant succeeded.
现在,B
可以执行包并修改数据
SQL> exec a.update_foo.set_val( 2 );
PL/SQL procedure successfully completed.
SQL> select * from foo;
COL1
----------
2
然而,总的来说,这不是一个特别明智的方法。一般来说,在一个模式中包含代码而在另一个模式中包含对象的全部意义在于提供职责分离和职责分离。如果您必须以UPDATE
无论如何都可以对表发出 an 的用户身份登录,那么拥有一个包来执行它并不会增加太多安全性。在这种情况下,它只是增加了复杂性。