Oracle 細粒度存取控制(FGAC),通稱 VPD,於 Oracle 8i 推出,提供列級安全。核心機制:查詢執行時透明附加謂詞,過濾不可見資料列。例:
-- 原始查詢
SELECT * FROM accounts;
-- VPD 自動重寫
SELECT * FROM accounts WHERE am_name = 'SCOTT';
DBA 在表上建立安全策略,關聯 策略函數 回傳謂詞字串(如 WHERE am_name = 'SCOTT')。
謂詞常含動態部分(如用戶身份、權限層級、應用上下文變數)。為保證正確性,Oracle 須每次執行重新評估策略函數,消耗資源、降低效能。此為 Oracle 9i 及之前預設的 DYNAMIC 策略。
| 策略類型 | 適用場景 | 謂詞特徵 | 重新評估機制 |
|---|---|---|---|
| CONTEXT_SENSITIVE | 謂詞前段靜態,後段依賴應用上下文(如 SYS_CONTEXT('VPDCTX','MAXBAL')) | 上下文不變時謂詞恆定 | 會話期間上下文未變則不重新執行函數 |
| SHARED_CONTEXT_SENSITIVE | 多表共用相同策略函數(如 SAVINGS/CHECKING 表同規則) | 同上,且跨物件共用 | 同會話、同上下文、不同表查詢時不重複執行 |
| STATIC | 謂詞完全由登入用戶決定,會話期間不變(如帳戶經理只看自屬客戶) | 全靜態,僅依 USER_ID | SGA 快取謂詞,僅首次執行函數 |
| SHARED_STATIC | 多表共用靜態策略函數 | 全靜態且跨物件共用 | 同 STATIC,進一步跨表共用快取 |
CREATE OR REPLACE FUNCTION vpd_pol_func (
p_schema IN VARCHAR2, p_table IN VARCHAR2
) RETURN VARCHAR2 IS
BEGIN
RETURN 'balance < SYS_CONTEXT(''VPDCTX'', ''MAXBAL'')';
END;
BEGIN
DBMS_RLS.ADD_POLICY(
object_schema => 'SCOTT',
object_name => 'ACCOUNTS',
policy_name => 'BALANCE_LIMIT',
function_schema => 'SEC_ADMIN',
policy_function => 'VPD_POL_FUNC',
policy_type => DBMS_RLS.CONTEXT_SENSITIVE -- 關鍵參數
);
END;
優勢:極致效能,函數只執行一次。
風險:若會話中應用上下文被修改(如 MAXBAL 變更),謂詞不會更新,導致資料洩露或錯誤過濾。
原則:唯有 100% 確定會話期間上下文不變 才可用 STATIC;否則退而求其次用 CONTEXT_SENSITIVE。
場景:SAVINGS、CHECKING 兩表共用同一餘額限制邏輯。
若用 CONTEXT_SENSITIVE 逐表建立策略,切換表時仍會重複執行函數。
改用 SHARED_CONTEXT_SENSITIVE,同會話、同上下文下,跨表查詢零額外開銷。