1、執行的schema不同,操作的對象也不同
在定義者(definer)權限下,執行的用戶操作的schema爲定義者,所操作的對象是定義者在編譯時指定的對象。
在調用者(invoker)權限下,執行的用戶操作的schema爲當前用戶,所操作的對象是當前模式下的對象。
例如:
[php]
E:\ora10g>sqlplus "/ as sysdba"
連接到:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL>create user tmpa identified by tmpa;
用戶已創建。
SQL>grant connect,resource to tmpa;
授權成功。
SQL>create user tmpb identified by tmpb;
用戶已創建。
SQL>grant connect,resource to tmpb;
授權成功。
SQL>conn tmpa/tmpa
已連接。
SQL>set sqlprompt TMPA>
TMPA>create table tmptbl(str varchar2(50));
表已創建。
TMPA>insert into tmptbl values ('I''m ownered by user:tmpa');
已創建 1 行。
TMPA>commit;
提交完成。
TMPA>create or replace procedure definer_proc as
2 begin
3 for x in (select sys_context('userenv', 'current_user') current_user,
4 sys_context('userenv', 'session_user') session_user,
5 sys_context('userenv', 'current_schema') current_schema,
6 str
7 from tmptbl) loop
8 dbms_output.put_line('Current User: ' || x.current_user);
9 dbms_output.put_line('Session User: ' || x.session_user);
10 dbms_output.put_line('Current Schema: ' || x.current_schema);
11 dbms_output.put_line('Tables Value: ' || x.str);
12 end loop;
13 end;
14 /
過程已創建。
TMPA>create or replace procedure invoker_proc AUTHID CURRENT_USER as
2 begin
3 for x in (select sys_context('userenv', 'current_user') current_user,
4 sys_context('userenv', 'session_user') session_user,
5 sys_context('userenv', 'current_schema') current_schema,
6 str
7 from tmptbl) loop
8 dbms_output.put_line('Current User: ' || x.current_user);
9 dbms_output.put_line('Session User: ' || x.session_user);
10 dbms_output.put_line('Current Schema: ' || x.current_schema);
11 dbms_output.put_line('Tables Value: ' || x.str);
12 end loop;
13 end;
14 /
過程已創建。
TMPA>set serveroutput on
TMPA>grant execute on definer_proc to tmpb;
授權成功。
TMPA>grant execute on invoker_proc to tmpb;
授權成功。
TMPA>exec definer_proc;
Current User: TMPA
Session User: TMPA
Current Schema: TMPA
Tables Value: I'm ownered by user:tmpa
PL/SQL 過程已成功完成。
TMPA>exec invoker_proc;
Current User: TMPA
Session User: TMPA
Current Schema: TMPA
Tables Value: I'm ownered by user:tmpa
PL/SQL 過程已成功完成。
[/php]
可以看到,對於owner所擁有的對象,當前用戶和session用戶都是當前執行過程的用戶;
新開一個連接,以tmpb用戶登陸再執行看看:
[php]
E:\ora10g>sqlplus tmpb/tmpb
連接到:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> set sqlprompt TMPB>
TMPB>create table tmptbl(str varchar2(50));
表已創建。
TMPB>insert into tmptbl values ('I''m ownered by user:tmpb');
已創建 1 行。
TMPB>commit;
提交完成。
TMPB>set serveroutput on
TMPB>exec tmpa.definer_proc;
Current User: TMPA
Session User: TMPB
Current Schema: TMPA
Tables Value: I'm ownered by user:tmpa
PL/SQL 過程已成功完成。
TMPB>exec tmpa.invoker_proc;
Current User: TMPB
Session User: TMPB
Current Schema: TMPB
Tables Value: I'm ownered by user:tmpb
PL/SQL 過程已成功完成。
[/php]
調用非owner的過程,對於定義者權限的過程,雖然session是tmpb,但當前用戶仍然是tmpa,訪問的對象也是tmpa的表,而對於調用者權限的過程,當前session和用戶都是當前執行過程的用戶tmpb,而且訪問的對象也是當前用戶的對象。
2、執行的權限不同
在定義者(definer)權限下,當前用戶的權限爲角色無效情況下所擁有的權限。
在調用者(invoker)權限下,當前用戶的權限爲當前所擁有的權限(含角色)。
例如:
仍用前文中的用戶
[php]
TMPA>create or replace procedure createtbl_definer as
2 begin
3 execute immediate 'create table tmptbl2 (id number)';
4 end;
5 /
過程已創建。
TMPA>create or replace procedure createtbl_invoker AUTHID CURRENT_USER as
2 begin
3 execute immediate 'create table tmptbl2 (id number)';
4 end;
5 /
過程已創建。
--
[/php]
首先執行定義者權限過程:
[php]
TMPA>exec createtbl_definer;
BEGIN createtbl_definer; END;
*
第 1 行出現錯誤:
ORA-01031: 權限不足
ORA-06512: 在 "TMPA.CREATETBL_DEFINER", line 3
ORA-06512: 在 line 1
--
[/php]
由於角色無效,相當於當前用戶沒有了建表權限,因此創建失敗,這也正是爲什麼過程中執行DDL語句需要顯示授權的原因。
[php]
TMPA>exec createtbl_invoker;
PL/SQL 過程已成功完成。
TMPA>desc tmptbl2
名稱 是否爲空? 類型
----------------------------------------- -------- ----------------------------
ID NUMBER
--
[/php]
執行調用者權限過程,能夠成功創建!
3、執行的效率不同
在定義者(definer)權限下,過程被靜態編譯靜態執行(相對而言),所執行sql語句在共享區池中是可被共享使用的
在調用者(invoker)權限下,過程靜態編譯,但動態執行,雖然執行的語句相同,但不同用戶執行,其sql語句在共享池中並不能共享。
歸根結底,正如tom所說,調用者權限體系結構的確擁有非常強大的功能,但只有當你使用得當時才能感受到其優勢。