Oracle

為什麼我可以執行這個查詢卻看不到它的執行計劃?

  • June 3, 2016

考慮以下查詢:

SELECT table_name,
 to_number(extractvalue(xmltype(dbms_xmlgen.getxml('select count(*) c from '
 ||owner
 ||'.'
 ||table_name)),'/ROWSET/ROW/C')) AS COUNT
FROM all_tables
WHERE UPPER(owner) = UPPER('my_schema');

此查詢執行良好並顯示輸出。但是對此查詢執行 EXPLAIN 會產生:

ORA-01039: 視圖底層對象的權限不足

根據 Oracle 文件:

您必須具有執行要為其確定執行計劃的 SQL 語句所需的權限。如果 SQL 語句訪問視圖,則您必須具有訪問該視圖所基於的任何表和視圖的權限。

要檢查 EXPLAIN PLAN 語句生成的執行計劃,您必須具有查詢輸出表所需的權限。

  1. 當查詢執行良好時,我確實對 SQL 訪問的表具有特權。
  2. 通過輸出表,我假設它意味著dbms_xplan.display儲存計算的計劃。我認為我對此有特權,並且以下執行良好:
EXPLAIN PLAN FOR SELECT * FROM myschema.mytable;
SELECT * FROM TABLE(dbms_xplan.display);

這裡缺少什麼?

當查詢執行良好時,我確實對 SQL 訪問的表具有特權。

這是一個錯誤的假設。僅僅因為您可以查詢視圖,並不一定意味著您對基礎表具有特權。任何人都可以查詢視圖ALL_TABLES,但普通使用者沒有權限查詢基礎表,例如OBJ$or TAB$

這就是它的工作原理,並且非常容易複製。創建兩個使用者,一個具有表和視圖,然後SELECT將該視圖授予另一個使用者:

SQL> grant create session, create table, create view to u1 identified by u1;

Grant succeeded.

SQL> grant create session to u2 identified by u2;

Grant succeeded.

SQL> create table u1.t1(id number);

Table created.

SQL> create view u1.v1 as select * from u1.t1;

View created.

SQL> grant select on u1.v1 to u2;

Grant succeeded.

現在連接為 u2,並嘗試從視圖中選擇:

SQL> connect u2/u2
Connected.

SQL> select * from u1.v1;

no rows selected

沒問題。現在試著解釋一下:

SQL> explain plan for select * from u1.v1;
explain plan for select * from u1.v1
                                 *
ERROR at line 1:
ORA-01039: insufficient privileges on underlying objects of the view

在 Oracle 文件中,它說您有一個EXPLAIN_PLAN表來儲存資訊:

在發出 EXPLAIN PLAN 語句之前,您必須有一個表來保存其輸出。PLAN_TABLE 是 EXPLAIN PLAN 語句插入描述執行計劃的行的預設範例輸出表。使用 SQL 腳本 UTLXPLAN.SQL 在您的模式中創建 PLAN_TABLE。此腳本的確切名稱和位置取決於您的作業系統。在 Unix 上,它位於 $ORACLE_HOME/rdbms/admin 目錄中。

執行此腳本,您將能夠使用EXPLAIN PLAN.

引用自:https://dba.stackexchange.com/questions/140321