我發現了這個問題。存儲過程的哪個模式運行?所有者的模式或調用者的模式?
- 用戶B具有一個存儲過程 「B.pk.sp」,和用戶A能夠讀取 「B.pk.sp」 並執行它。
- 過程「B.pk.sp」操縱不屬於架構向 用戶B
這讓我感到困惑的是,如果用戶A呼叫「B.sk.sp」將操作表用戶B表還是會操縱用戶A表?
謝謝你閱讀這個問題。
我發現了這個問題。存儲過程的哪個模式運行?所有者的模式或調用者的模式?
這讓我感到困惑的是,如果用戶A呼叫「B.sk.sp」將操作表用戶B表還是會操縱用戶A表?
謝謝你閱讀這個問題。
取決於您在定義過程時設置的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
,並且過程(或包)將在其所有者的模式(而不是調用者的模式)中操作表。
如果你真的想將編輯/操作本地化爲一個特定的用戶/模式,你可以使用同義詞或明確提到username.object –
@RogueCoder是的......但問題是「該過程操縱表**沒有模式**「;因此指定模式會使問題的前提失效。 – MT0
我認爲這取決於[授予/撤銷權限](https://www.techonthenet.com/oracle/grant_revoke.php) – Frank
這取決於b.pk.sp程序是否已經用[definer's或調用者的權利](http://docs.oracle.com/database/121/DBSEG/dr_ir.htm#DBSEG99925)。如果它具有定義者的權限(缺省值),那麼該過程將以用戶B的特權運行(即它將使用模式B中的表),否則它將以調用用戶的特權運行。 – Boneist
在Oracle中,當您訪問一個對象時,引擎將自動搜索屬於用戶(模式)的對象,然後搜索公共同義詞。因此,理論上,如果用戶A調用B.sk.sp,它將操縱用戶A表。但可能還有其他一些可能會改變這種行爲的事情(登錄觸發器,特權,......),所以您需要對其進行測試。 –