2017-08-02 20 views
1

我发现了这个问题。存储过程的哪个模式运行?所有者的模式或调用者的模式?

  • 用户B具有一个存储过程 “B.pk.sp”,和用户A能够读取 “B.pk.sp” 并执行它。
  • 过程“B.pk.sp”操纵不属于架构向 用户B

这让我感到困惑的是,如果用户A呼叫“B.sk.sp”将操作表用户B表还是会操纵用户A表?

谢谢你阅读这个问题。

+0

我认为这取决于[授予/撤销权限](https://www.techonthenet.com/oracle/grant_revoke.php) – Frank

+1

这取决于b.pk.sp程序是否已经用[definer's或调用者的权利](http://docs.oracle.com/database/121/DBSEG/dr_ir.htm#DBSEG99925)。如果它具有定义者的权限(缺省值),那么该过程将以用户B的特权运行(即它将使用模式B中的表),否则它将以调用用户的特权运行。 – Boneist

+1

在Oracle中,当您访问一个对象时,引擎将自动搜索属于用户(模式)的对象,然后搜索公共同义词。因此,理论上,如果用户A调用B.sk.sp,它将操纵用户A表。但可能还有其他一些可能会改变这种行为的事情(登录触发器,特权,......),所以您需要对其进行测试。 –

回答

5

取决于您在定义过程时设置的invoker rights clause (i.e. AUTHID CURRENT_USER)

甲骨文设置

CREATE USER A IDENTIFIED BY APassword; 
CREATE USER B IDENTIFIED BY BPassword; 

CREATE TABLE A.your_table (id) AS SELECT 'A' FROM DUAL; 
CREATE TABLE B.your_table (id) AS SELECT 'B' FROM DUAL; 

CREATE PROCEDURE A.test_invoker_rights(id OUT VARCHAR2) AUTHID CURRENT_USER 
AS 
BEGIN 
    SELECT id INTO id FROM your_table WHERE ROWNUM = 1; 
END; 
/
GRANT EXECUTE ON A.test_invoker_rights TO B; 

现在考虑的PL/SQL脚本:

SET SERVEROUTPUT ON; 
DECLARE 
    ID VARCHAR2(1); 
BEGIN 
    A.test_invoker_rights(id); 
    DBMS_OUTPUT.PUT_LINE(id); 
END; 
/

如果你运行它的用户A然后输出为A;但是如果以用户B运行它,则输出为B。现在

,如果重新定义的过程有头:

CREATE PROCEDURE A.test_invoker_rights(id OUT VARCHAR2) AUTHID DEFINER 

或默认调用者权限(通过省略that从句):

CREATE PROCEDURE A.test_invoker_rights(id OUT VARCHAR2) 

然后,如果你运行它的用户A则输出为A;但如果以用户B运行,则输出仍将为A

默认值为AUTHID DEFINER,并且过程(或包)将在其所有者的模式(而不是调用者的模式)中操作表。

+1

如果你真的想将编辑/操作本地化为一个特定的用户/模式,你可以使用同义词或明确提到username.object –

+2

@RogueCoder是的......但问题是“该过程操纵表**没有模式**“;因此指定模式会使问题的前提失效。 – MT0