小编典典

Oracle-函数不起作用

sql

Oracle-函数不起作用

所以我不知道我在做什么错。我已经花了几个小时了,非常感谢您的帮助。

因此,基本上我有2个表,一个表被称为主student列表,它是一个学生列表,student_no另一个表被调用enrol,它基本上具有该学生所注册课程的列表。

因此,我编写了一个函数,用于将登录学生的用户名(在本例中为)与student_no学生列表进行比较,并确保登录用户是学生。然后,它将student_noenrol表进行比较,以查找用户注册的任何程序。因此,从本质上讲,当我SELECT * FROM yaser.enrol(表所有者是yaser)时,我应该只从注册列表中看到几条记录。相反,我得到了错误:failed to execute policy function

这是我的职能:

-- Create policy function to be called when 'ENROL' table is accessed
create or replace function f_policy_enrol (schema in varchar2, tab in varchar2)
-- Function will return a string that is used as a WHERE clause                       
return varchar2
as
 v_student_no     varchar2(10);
 is_student       number:=0;
 v_user           varchar2(100);
 out_string       varchar2(400) default '1=2 ';

begin
  -- get session user
  v_user := lower(sys_context('userenv','session_user'));

  -- Is the user a student?
  begin
    select student_no into v_student_no from student where lower(student_no) = v_user;
    is_student:=1;
  exception
    when no_data_found then
    v_student_no := 0;
  end;

  -- If it's a student, then they are only allowed to see their record only.
  if is_student = 1 then
     out_string := out_string||'or student_no = '||v_student_no||' ';
  end if;

  return out_string;
end;
/

这是我引用的政策:

begin
dbms_rls.add_policy('yaser',
                    'enrol',
                    'accesscontrol_enrol',
                    'yaser',
                    'f_policy_enrol',
                    policy_type => dbms_rls.context_sensitive);
end;
/

如前所述..我不确定我要去哪里错了。无论是在策略还是功能上。任何帮助将不胜感激!如果您有任何疑问,只要有空闲时间,我就会很乐意回答!

提前致谢!

亚瑟


阅读 187

收藏
2021-04-14

共1个答案

小编典典

student_no列的数据类型是什么?列名暗示它是一个NUMBER。但是,您正在调用lower它并将其与会话用户进行比较的事实意味着它是一个VARCHAR2

假设student_noVARCHAR2,则一个问题是您的谓词缺少该值周围的单引号。如果v_student_no是,例如“
jcave”,则您out_string

1=2 or student_no = jcave

由于未引用“
jcave”,因此Oracle假定它必须是标识符,因此它将在名为的表中查找列jcave。没有找到这样的列,它将引发错误。如果在字符串两边加上单引号,则会更有运气

out_string := out_string||'or student_no = '''||v_student_no||''' ';

可能还会有其他错误。您是否尝试过手动调用该函数以查看其返回的确切信息?如果您在session_user设置为“
jcave”时手动调用了该函数,那么您应该已经看到缺少单引号的结果。如果您复制并粘贴返回值并将其添加到SELECT语句的末尾,则会立即看到错误。v$vpd_policy如果要避免手动调用该函数,还可以查询以查看已添加到特定SQL语句中的特定策略谓词-
当您尝试调试会话状态为VPD的VPD问题时,这非常有用。您不容易复制。

2021-04-14