呼叫者許可權與定義者許可權的pl/sql子程式
對於pl/sql子程式的呼叫來說,具有兩種方式:定義者許可權和呼叫者許可權。
所謂定義者許可權,表示的是在執行pl/sql子程式的時候,參考的是建立該pl/sql子程式的使用者所擁有的許可權。同時,pl/sql子程式在執行時,對於牽涉到的表或者其他物件,也都參考建立該pl/sql子程式的使用者所擁有的物件。而執行該pl/sql子程式的使用者不需要具有訪問建立該pl/sql子程式的使用者下的表的許可權。預設情況下,pl/sql子程式都以定義者許可權來執行。
比如:
SQL> connect / as sysdba
已連線。
SQL> create user u1 identified by u1;
使用者已建立
SQL> grant create session to u1;
授權成功。
SQL> connect u1/u1
已連線。
SQL> select last_name from hr.employees where employee_id=101;
select last_name from hr.employees where employee_id=101
*
ERROR 位於第 1 行:
ORA-00942: 表或檢視不存在
SQL> connect hr/hr
已連線。
SQL> CREATE OR REPLACE PROCEDURE p_get_lastname
2 (v_employee_id IN employees.employee_id%TYPE,
3 v_last_name OUT employees.last_name%TYPE) IS
4 BEGIN
5 SELECT last_name
6 INTO v_last_name
7 FROM employees
8 WHERE employee_id = v_employee_id;
9 END;
10 /
過程已建立。
SQL> grant execute on p_get_lastname to u1;
授權成功。
SQL> connect u1/u1
已連線。
SQL> var ls_lastname varchar2(50);
SQL> exec hr.p_get_lastname(101,:ls_lastname);
PL/SQL 過程已成功完成。
SQL> print ls_lastname;
LS_LASTNAME
----------------------------------------------
Kochhar
可以很明顯看到,定義者許可權中,u1沒有許可權檢視hr.employees表裡的資料,但是u1具有執行hr.p_get_lastname的許可權,從而它可以獲取hr.employees表裡的記錄。
而定義者許可權則不同。它在執行pl/sql子程式的時候,參考的是執行者的許可權。同時,pl/sql子程式在執行時,對於牽涉到的表或者其他物件,也都參考執行該pl/sql子程式的使用者所擁有的物件。
比如:
SQL> connect / as sysdba
已連線。
SQL> create user u2 identified by u2 ;
使用者已建立
SQL> grant create session to u2;
授權成功。
SQL> connect hr/hr
已連線。
SQL> CREATE OR REPLACE PROCEDURE p_get_lastname2
2 (v_employee_id IN employees.employee_id%TYPE,
3 v_last_name OUT employees.last_name%TYPE)
4 authid current_user
5 IS
6 BEGIN
7 SELECT last_name
8 INTO v_last_name
9 FROM employees
10 WHERE employee_id = v_employee_id;
11 END;
12 /
過程已建立。
注意,這裡新增的authid current_user就表示該儲存過程為呼叫者許可權。
SQL> grant execute on p_get_lastname2 to u2;
授權成功。
SQL> connect u2/u2
已連線。
SQL> var ls_lastname varchar2(50);
SQL> exec hr.p_get_lastname2(101,:ls_lastname);
BEGIN hr.p_get_lastname2(101,:ls_lastname); END;
*
ERROR 位於第 1 行:
ORA-00942: 表或檢視不存在
ORA-06512: 在"HR.P_GET_LASTNAME2", line 7
ORA-06512: 在line 1
可以看的很清楚,這裡的錯誤為:ORA-00942: 表或檢視不存在。實際也就是hr.p_get_lastname2裡訪問的employees表不存在於當前u2使用者下。
SQL> connect / as sysdba
已連線。
SQL> grant create table to u2;
授權成功。
SQL> alter user u2 quota 5M on users;
使用者已更改。
SQL> connect u2/u2
已連線。
SQL> create table employees(employee_id number,last_name varchar2(50)) tablespace users;
表已建立。
SQL> insert into employees values(101,'hansijie');
已建立 1 行。
SQL> commit;
提交完成。
SQL> exec hr.p_get_lastname2(101,:ls_lastname);
PL/SQL 過程已成功完成。
SQL> print ls_lastname;
LS_LASTNAME
-------------------------------------------------
hansijie
可以看到,當我在u2下建立了employees表以後,就會訪問到u2下的employees表裡的記錄了。
對於定義者許可權的pl/sql子程式來說,通過角色傳入的許可權是不能作用於儲存過程裡面的。比如:
SQL> create user red identified by red;
使用者已建立
SQL> grant dba to red;
授權成功。
SQL> connect red/red
已連線。
SQL> create or replace procedure p_test
2 is
3 begin
4 dbms_utility.exec_ddl_statement('grant dba to u1');
5 end;
6 /
過程已建立。
SQL> exec p_test;
BEGIN p_test; END;
*
ERROR 位於第 1 行:
ORA-01031: 許可權不足
ORA-06512: 在"SYS.DBMS_SYS_SQL", line 826
ORA-06512: 在"SYS.DBMS_SQL", line 32
ORA-06512: 在"SYS.DBMS_UTILITY", line 550
ORA-06512: 在"RED.P_TEST", line 4
ORA-06512: 在line 1
這時可以看到,說的很清楚,許可權不足。但是red使用者已經具有了dba許可權了,為何還會報許可權不足呢?這就是因為這是一個定義者許可權的pl/sql子程式,在執行grant dba to u1的時候,不能獲得dba這個角色所傳遞過來的許可權。你可以把該儲存過程改為呼叫者許可權,表示參考呼叫者所擁有的許可權。
SQL> create or replace procedure p_test
2 authid current_user
3 is
4 begin
5 dbms_utility.exec_ddl_statement('grant dba to u1');
6 end;
7 /
過程已建立。
SQL> exec p_test;
PL/SQL 過程已成功完成。
這時就能正確執行了。
所謂定義者許可權,表示的是在執行pl/sql子程式的時候,參考的是建立該pl/sql子程式的使用者所擁有的許可權。同時,pl/sql子程式在執行時,對於牽涉到的表或者其他物件,也都參考建立該pl/sql子程式的使用者所擁有的物件。而執行該pl/sql子程式的使用者不需要具有訪問建立該pl/sql子程式的使用者下的表的許可權。預設情況下,pl/sql子程式都以定義者許可權來執行。
比如:
SQL> connect / as sysdba
已連線。
SQL> create user u1 identified by u1;
使用者已建立
SQL> grant create session to u1;
授權成功。
SQL> connect u1/u1
已連線。
SQL> select last_name from hr.employees where employee_id=101;
select last_name from hr.employees where employee_id=101
*
ERROR 位於第 1 行:
ORA-00942: 表或檢視不存在
SQL> connect hr/hr
已連線。
SQL> CREATE OR REPLACE PROCEDURE p_get_lastname
2 (v_employee_id IN employees.employee_id%TYPE,
3 v_last_name OUT employees.last_name%TYPE) IS
4 BEGIN
5 SELECT last_name
6 INTO v_last_name
7 FROM employees
8 WHERE employee_id = v_employee_id;
9 END;
10 /
過程已建立。
SQL> grant execute on p_get_lastname to u1;
授權成功。
SQL> connect u1/u1
已連線。
SQL> var ls_lastname varchar2(50);
SQL> exec hr.p_get_lastname(101,:ls_lastname);
PL/SQL 過程已成功完成。
SQL> print ls_lastname;
LS_LASTNAME
----------------------------------------------
Kochhar
可以很明顯看到,定義者許可權中,u1沒有許可權檢視hr.employees表裡的資料,但是u1具有執行hr.p_get_lastname的許可權,從而它可以獲取hr.employees表裡的記錄。
而定義者許可權則不同。它在執行pl/sql子程式的時候,參考的是執行者的許可權。同時,pl/sql子程式在執行時,對於牽涉到的表或者其他物件,也都參考執行該pl/sql子程式的使用者所擁有的物件。
比如:
SQL> connect / as sysdba
已連線。
SQL> create user u2 identified by u2 ;
使用者已建立
SQL> grant create session to u2;
授權成功。
SQL> connect hr/hr
已連線。
SQL> CREATE OR REPLACE PROCEDURE p_get_lastname2
2 (v_employee_id IN employees.employee_id%TYPE,
3 v_last_name OUT employees.last_name%TYPE)
4 authid current_user
5 IS
6 BEGIN
7 SELECT last_name
8 INTO v_last_name
9 FROM employees
10 WHERE employee_id = v_employee_id;
11 END;
12 /
過程已建立。
注意,這裡新增的authid current_user就表示該儲存過程為呼叫者許可權。
SQL> grant execute on p_get_lastname2 to u2;
授權成功。
SQL> connect u2/u2
已連線。
SQL> var ls_lastname varchar2(50);
SQL> exec hr.p_get_lastname2(101,:ls_lastname);
BEGIN hr.p_get_lastname2(101,:ls_lastname); END;
*
ERROR 位於第 1 行:
ORA-00942: 表或檢視不存在
ORA-06512: 在"HR.P_GET_LASTNAME2", line 7
ORA-06512: 在line 1
可以看的很清楚,這裡的錯誤為:ORA-00942: 表或檢視不存在。實際也就是hr.p_get_lastname2裡訪問的employees表不存在於當前u2使用者下。
SQL> connect / as sysdba
已連線。
SQL> grant create table to u2;
授權成功。
SQL> alter user u2 quota 5M on users;
使用者已更改。
SQL> connect u2/u2
已連線。
SQL> create table employees(employee_id number,last_name varchar2(50)) tablespace users;
表已建立。
SQL> insert into employees values(101,'hansijie');
已建立 1 行。
SQL> commit;
提交完成。
SQL> exec hr.p_get_lastname2(101,:ls_lastname);
PL/SQL 過程已成功完成。
SQL> print ls_lastname;
LS_LASTNAME
-------------------------------------------------
hansijie
可以看到,當我在u2下建立了employees表以後,就會訪問到u2下的employees表裡的記錄了。
對於定義者許可權的pl/sql子程式來說,通過角色傳入的許可權是不能作用於儲存過程裡面的。比如:
SQL> create user red identified by red;
使用者已建立
SQL> grant dba to red;
授權成功。
SQL> connect red/red
已連線。
SQL> create or replace procedure p_test
2 is
3 begin
4 dbms_utility.exec_ddl_statement('grant dba to u1');
5 end;
6 /
過程已建立。
SQL> exec p_test;
BEGIN p_test; END;
*
ERROR 位於第 1 行:
ORA-01031: 許可權不足
ORA-06512: 在"SYS.DBMS_SYS_SQL", line 826
ORA-06512: 在"SYS.DBMS_SQL", line 32
ORA-06512: 在"SYS.DBMS_UTILITY", line 550
ORA-06512: 在"RED.P_TEST", line 4
ORA-06512: 在line 1
這時可以看到,說的很清楚,許可權不足。但是red使用者已經具有了dba許可權了,為何還會報許可權不足呢?這就是因為這是一個定義者許可權的pl/sql子程式,在執行grant dba to u1的時候,不能獲得dba這個角色所傳遞過來的許可權。你可以把該儲存過程改為呼叫者許可權,表示參考呼叫者所擁有的許可權。
SQL> create or replace procedure p_test
2 authid current_user
3 is
4 begin
5 dbms_utility.exec_ddl_statement('grant dba to u1');
6 end;
7 /
過程已建立。
SQL> exec p_test;
PL/SQL 過程已成功完成。
這時就能正確執行了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9842/viewspace-329702/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Django(63)drf許可權原始碼分析與自定義許可權Django原始碼
- sql許可權管理SQL
- android動態許可權到自定義許可權框架Android框架
- 選單許可權和按鈕許可權設定
- 許可權之選單許可權
- linux 檔案許可權 s 許可權和 t 許可權解析Linux
- 如何用 Vue 實現前端許可權控制(路由許可權 + 檢視許可權 + 請求許可權)Vue前端路由
- hadoop自定義許可權Hadoop
- 小程式許可權設定(位置)
- DRF內建許可權元件之自定義許可權管理類元件
- Linux使用者與許可權Linux
- 許可權系統:一文搞懂功能許可權、資料許可權
- NAS使用者許可權的設定
- 如何檢查某個使用者是否具有某個許可權物件上定義的某種許可權物件
- 如何使用Linux使用者身份與程式許可權的設定?Linux
- Linux的檔案存取許可權和0644許可權Linux
- MongoDB 使用者與許可權管理MongoDB
- Linux特殊許可權之suid、sgid、sbit許可權LinuxUI
- 【自然框架】許可權的視訊演示(二):許可權到欄位、許可權到記錄框架
- ubuntu 許可權管理設定Ubuntu
- PostgreSQL物件許可權如何在後設資料中獲取-許可權解讀、定製化匯出許可權SQL物件
- SpringSecurity:hasAuthority與自定義許可權校驗SpringGse
- mysql許可權MySql
- 許可權控制
- Linux許可權Linux
- linux使用者許可權Linux
- django開發之許可權管理(一)——許可權管理詳解(許可權管理原理以及方案)、不使用許可權框架的原始授權方式詳解Django框架
- 造輪子之許可權管理
- 阿里雲RDS的高許可權不是真正的高許可權阿里
- windows10許可權怎麼設定_win10設定使用者許可權的方法WindowsWin10
- Android6.0------許可權申請管理(單個許可權和多個許可權申請)Android
- 入門MySQL——使用者與許可權MySql
- MySQL入門--使用者與許可權MySql
- 類的許可權與應用
- MYSQL學習筆記13: DCL許可權控制(使用者許可權操作)MySql筆記
- Linux 如何設定特殊許可權?Linux
- 許可權系統:許可權應用服務設計
- [BUG反饋]許可權條目中缺少兩個公開方法的許可權設定