1. 程式人生 > >ORACLE儲存過程執行報“ora-00942表或檢視不存在”、“ORA-01031:許可權不足”的解決方式

ORACLE儲存過程執行報“ora-00942表或檢視不存在”、“ORA-01031:許可權不足”的解決方式

目錄:

一、案例

二、思索過程

三、解決方案

四、後記

正文

一、案例:

在userA使用者下書寫儲存過程如下:

create or replace procedure sp_test is
  v_str1          varchar2(1000);
begin
  v_str1 := 'ALTER TABLE userB.tb_user_info_m truncate PARTITION P201311';
  execute immediate(v_str1);
end sp_test;


然後在plsql中測試,結果ORACLE非常無情地報

ORA-01031:許可權不足。

臨近春節,怕資料空間爆滿,想刪資料,oracle真的很不給面子。

所以我要征服它~~~~

二、思索過程

1. 將關鍵部位拷貝出來,直接在userA使用者下執行,完全沒有異常(本例中Sqlplus和plsql中執行結果非常一致,因此和執行環境沒有關係,下同):

SQL> ALTER TABLE userB.tb_user_info_m truncate PARTITION P201311;

2. 第一個步驟說明使用者userA使用者許可權是沒有問題的。

3. 在儲存過程中將v_str1更改為select語句,結果也是報錯,不過不是許可權不足,是“ora-00942表或檢視不存在”,說明在儲存過程中無法查詢其他使用者的表:

v_str1 := 'select count(1) into v_integer from userB.tb_user_info_m'; 

4. 使用其他使用者userC建立儲存過程(這個使用者一直是用來建立表分割槽用的,所以肯定是可以通過的)。結果確實通過了:

create or replace procedure userC.sp_test is
  v_str1          varchar2(1000);
begin
  v_str1 := 'ALTER TABLE userB.tb_user_info_m truncate PARTITION P201311';
  execute immediate(v_str1);
end sp_test;
begin
  sp_test;
end;

“已完成,耗時1.294秒”

5. 第4步說明儲存過程寫法是沒有錯的。問題還是出在許可權上。

6. 對比userA和userC兩個使用者的許可權,一個個許可權賦予userA,發現結果執行到:grant select any table to userA; 第3步中的select語句執行通過了;

繼續賦權:grant drop ant table to userA; 的時候案例中的儲存過程執行通過。

7. 第6步說明問題還是出在許可權上面。但是直接執行又沒有問題,研究具體的副權語句,發現userA是通過許可權組獲得select any table 和 drop any table 許可權的,而userC是直接在sys使用者下執行賦any 權的語句的。因此,猜測問題是出在許可權繼承的問題上。

8. 新建userD,使用許可權組賦權:grant role_group to userD; 同樣是報“ora-00942” 和“ORA-01031” 的。去掉許可權後直接賦權:grant drop ant table to userA; 儲存過程執行完畢。

9. 思考結束。

三、解決方案如下:

使用sys使用者直接賦權(select、insert、update、delete、alter、drop),而不要用許可權組的方式賦權。因為儲存過程中無法繼承非直接賦予的許可權。

四、後記:

其實alter許可權我一開始也是單獨賦予了,但是卻還是報許可權不足,無論是truncate還是drop表分割槽

留意字眼,不是alter表而已,而是alter的時候對錶分割槽進行操作,因此truncate和drop的許可權都要賦予,不然是無法操作的。

走了很多彎路,最後幸好有個前面的例子在,才解決了。

網上說的很多都是沒有作用的,諸如什麼:“在目標使用者下使用grant語句”等等,確實,是能夠達到效果的,但是我要賦權幾千個表,而且後續還有新加入的表,全部都需要手動進行賦權,都苦逼啊。直接在sys下進行any table的賦權,能省去不少功夫。

plus:如果sys沒有給予對應使用者with admin option的許可權的話,是沒有辦法在userB等非sys使用者使用any table 選項的。

後記全部是廢話,不看也罷。