1

Generic_Schema 有一个公用表 GENERIC_TABLE。GENERIC_TABLE 的主键是 COL1 和 COMPANY_ID。

Company_id     Col1 Col2 Col3
-------------- ---- ---- ----
ALL_COMPANIES  A    B    C
Comp1          A    B1   C1
Comp3          A    B3   C

特定公司架构

  1. Schema1 => Comp1
  2. Schema2 => Comp2
  3. SchemaN =>CompN

我们已经在 GENERIC_TABLE 上实现了 RLS。RLS 函数返回一个 clob 值,但在函数内部检索过滤器值的逻辑是:

  1. 将键与其他值进行比较,如果 Comp1 Schema 请求数据,则检索 A|B1|C1 数据并且不检索 ALL_COMPANIES 数据,因为表中存在公司特定值。
  2. 如果 Comp4 检索数据,它将只获得 A|B|C 记录。
  3. 过滤条件需要从另一个返回 rowid 的函数中检索。

现在,问题来了。实施后,RLS 的运行时间要高得多,尽管我们没有看到太多的 I/O。任何人都可以认为这种设计是一个问题,因为这不是一个静态谓词,它是上下文相关的。如果您需要更多输入,请告诉我。

函数定义是

create or replace function
  book_access_policy
  (obj_schema varchar2, obj_name varchar2)
  return clob

 is

CURSOR get_d_predicate
IS
 SELECT /*+ RESULT_CACHE */ rd
  FROM
  (
  SELECT rowid rd
        ,DENSE_RANK() OVER(PARTITION BY COL1 ORDER BY CASE WHEN COMPANY_ID = sys_context('publishing_application','company_id') THEN 1 ELSE 2 END) rnk
FROM GENERIC_TABLE
  )
   WHERE rnk=1;

get_d_predicate_rec get_d_predicate%ROWTYPE;
d_predicate clob;

begin

 if sys_context('publishing_application','company_id') IS NULL THEN
  d_predicate:= ' 1=1';

 else
   d_predicate =' rowid in ('
    OPEN get_d_predicate;
    LOOP
     FETCH get_d_predicate INTO get_d_predicate_rec;
     EXIT WHEN get_d_predicate%NOTFOUND;
       d_predicate = d_predicate|| get_d_predicate_rec.rd;
    END LOOP;
   CLOSE get_d_predicate;
    d_predicate:=d_predicate||')';


 end if;

return d_predicate;

 end;
 /
4

0 回答 0