2017-08-02 21 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