我发现了这个问题。存储过程的哪个模式运行?所有者的模式或调用者的模式?
- 用户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表。但可能还有其他一些可能会改变这种行为的事情(登录触发器,特权,......),所以您需要对其进行测试。 –