所以我有几个表,我已经创建了不同的角色来与不同的用户一起使用,这样每个人都可以访问一部分表。
现在,每当我尝试SELECT * FROM yaser.enrol;
与协调员打算查看所有内容时,我都会收到错误numeric or value error: character to number conversion error
,该错误指向我正在查询employee_no
的行确定员工角色。
Theres 4种类型的用户:学生,导师,讲师,协调员。
编辑** 添加了所有代码。
-- Create policy function to be called when ‘ENROL’ table is accessed under user Yaser.
create or replace function f_policy_enrol (schema in varchar2, tab in varchar2)
return varchar2
as
v_emp_no varchar2(10);
v_student_no varchar2(10);
v_tutor_emp_no varchar2(10);
v_lecturer_emp_no varchar2(10);
v_coord_emp_no varchar2(10);
is_tutor number:=0;
is_lecturer number:=0;
is_coordinator number:=0;
is_student number:=0;
is_employee number:=0;
v_program_code varchar2(10);
v_user varchar2(100);
out_string varchar2(400) default '1=2 ';
-- The return value will be out_string. '1=2' means 'Nothing to access'.
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;
-- Is the user an employee?
begin
SELECT emp_no INTO v_emp_no FROM employee WHERE lower(emp_no) = v_user;
is_employee:=1;
exception
when no_data_found then
v_emp_no := 0;
end;
-- Query the employee number to determine role.
-- If Tutor.
SELECT MAX(tutor_emp_no) INTO v_tutor_emp_no FROM tutorial WHERE lower(tutor_emp_no) = v_user;
-- If Lecturer.
SELECT MAX(course_coord_emp_no) INTO v_lecturer_emp_no FROM course WHERE lower(course_coord_emp_no) = v_user;
-- If Coordinator.
SELECT MAX(prog_coord_emp_no) into v_coord_emp_no FROM program WHERE lower(prog_coord_emp_no) = v_user;
-- Get role of the employee if the user is an employee.
if v_emp_no != 0 and v_tutor_emp_no is NOT NULL then
-- Employee is a Tutor.
is_tutor := 1;
elsif v_emp_no != 0 and v_lecturer_emp_no is NOT NULL then
-- Employee is Lecturer.
is_lecturer := 1;
elsif v_emp_no != 0 and v_coord_emp_no is NOT NULL then
-- Employee is Coordinator.
is_coordinator := 1;
end if;
-- Create the string to be used as the WHERE clause.
if is_student = 1 then
-- Students are allowed to see their orders only.
out_string := out_string||'or student_no = '''||v_student_no||''' ';
end if;
if is_tutor = 1 then
-- Tutors are allowed to see enrolments of students that they tutor.
---- out_string := out_string||'or student_no in (select student_no from tutorial where tutor_emp_no = '||v_tutor_emp_no||') ';
---- NOT WORKING.
out_string := out_string||'or student_no in (select student_no from tutorial where lower(tutor_emp_no) = v_tutor_emp_no) ';
end if;
if is_coordinator = 1 then
-- The coordinator is allowed to see all records in ENROL (WHERE 1=1 or anything) means all rows.
out_string := out_string||'or 1=1 ';
end if;
return out_string;
end;
/
这些是我正在引用的表格:
CREATE TABLE course
(
course_code varchar(10),
course_title varchar(50),
course_coord_emp_no varchar(10),
primary key (course_code)
);
并且 - 所有员工:
CREATE TABLE employee
(
emp_no varchar(10),
name varchar(100)
);
所有其他表格基本相同 - VARCHARS
任何帮助都会很好! :) 亚瑟
答案 0 :(得分:1)
这个问题已经发展了一个很多,这个答案的大部分内容都是关于与您的实际代码无关的遗失end if
。实际上回到你的原始问题,使用or 1=1
作为一个包罗万象是好的,即使if
的另一个分支如果比较字符串 - 它没有区别一点都不如果你真的想比较字符串,你可以做同样的事情:
'or ''x''=''x'' '
......或
'or v_user=v_user '
但是你无法比较你在评论中显示的空字符串。空字符串''
与Oracle中的null
相同,您无法将任何内容等同于null
,甚至本身。 (如果v_user
为null
,则上一次检查将失败,原因相同)。另一种可能性是:
'or null is null '
请注意,此处的比较器为is
,而不是=
。
其中没有一个解决了为什么你会得到VPD错误,因为所有这些都是等效的 - 它们总是评估为真,并且你使用哪个并不重要。任何有效结束为or true
的东西都会完全相同;只是遗憾的是Oracle SQL不理解这样的布尔值。在任何其他子句中进行比较的数据类型与此子句无关。
在这两种情况下,您需要查看函数实际返回的内容,验证它是您所期望的,并在查询VPD直接反对的表时验证它是否作为限制。