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
特定公司架构
- Schema1 => Comp1
- Schema2 => Comp2
- SchemaN =>CompN
我们已经在 GENERIC_TABLE 上实现了 RLS。RLS 函数返回一个 clob 值,但在函数内部检索过滤器值的逻辑是:
- 将键与其他值进行比较,如果 Comp1 Schema 请求数据,则检索 A|B1|C1 数据并且不检索 ALL_COMPANIES 数据,因为表中存在公司特定值。
- 如果 Comp4 检索数据,它将只获得 A|B|C 记录。
- 过滤条件需要从另一个返回 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;
/