带有for循环策略功能的Oracle RLS / VPD

时间:2012-01-26 02:24:14

标签: sql oracle

这是关于最初讨论的Oracle行级安全功能的旧问题的后续问题here

我需要修改它,因为如果用户连接到多个项目,原始代码将返回多个结果。所以现在我需要将多个where条件(即project = project_1或project = project_2)传递给安全策略以使其工作。为此,我尝试使用for循环修改代码,但它不起作用......

--create function
create or replace function
   table_access_policy
   (obj_schema varchar2, obj_name varchar2) return varchar2

is                

v_project_temp varchar2(9000);

begin              

v_project_temp:= 'declare v_project varchar2(9000);

begin
v_project:= ''project = '';

for c in (select admin.access_list.project from admin.access_list where upper(admin.access_list.user_id) = SYS_CONTEXT (''USERENV'', ''SESSION_USER'')) 

loop

v_project := v_project || c.project_sn || '' or project = '' ;

end loop;

v_project := rtrim(v_project, '' or project = '');

end;';

return v_project_temp;

end;

该函数保存/运行没有任何错误,但是策略本身在调用时会抛出错误。有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

不是将PL / SQL放在字符串中,而是应该运行它并构建要返回的v_project字符串。如:

--create function
create or replace function
   table_access_policy
   (obj_schema varchar2, obj_name varchar2) return varchar2    
is
  v_project varchar2(9000);
begin              
  v_project:= 'project = ';
  for c in (select admin.access_list.project from admin.access_list where upper(admin.access_list.user_id) = SYS_CONTEXT ('USERENV', 'SESSION_USER')) 
  loop
    v_project := v_project ||''''|| c.project_sn ||''''|||| ' or project = ' ;
  end loop;    
  v_project := rtrim(v_project, ' or project = ');    
  return v_project;    
end;

最终v_project中显示的值将在SQL语句中的where后直接显示,例如:

select * from data;

将成为

select * from date where <v_project>;

因此只有where后面的内容才能进入v _ project