可能会提出类似的问题,如果是,请分享链接。
必需:
每当创建或更新新记录时,都需要验证该人的工资是否符合工作范围。
以下是触发器,
create or replace TRIGGER secure_employees_sal_range
BEFORE INSERT OR UPDATE OF salary,job_id ON employees
FOR EACH ROW
DECLARE
p_min_sal Integer;
p_max_sal Integer;
BEGIN
--check_salaray_range(employee_id,job_id,salary);
select min_salary, max_salary
into p_min_sal, p_max_sal
from jobs
where job_id = p_job_id;
if p_salary < p_min_sal OR p_salary > p_max_sal THEN
RAISE_APPLICATION_ERROR (-20225,
'Salray should in range' || p_min_sal || ' and ' || p_max_sal);
END IF;
END secure_employees_sal_range;
但我收到错误
第13行出错:PL / SQL:忽略语句
Line 14: where job_id = :new.job_id;
如何从员工表中设置p_job_id的值?
更新 现在在创建新员工时薪水超出范围时收到错误消息
ORA-20225:Salray应该在range4000和10000 ORA-06512:at&#34; HR.SECURE_EMPLOYEES_SAL_RANGE&#34;,第14行ORA-04088:执行触发期间的错误&#39; HR.SECURE_EMPLOYEES_SAL_RANGE&#39; 无法处理表EMPLOYEES的行。
然后,当尝试更新现有记录时,
ORA-20505:DML出错:p_rowid = 215,p_alt_rowid = EMPLOYEE_ID,p_rowid2 =,p_alt_rowid2 =。 ORA-20225:Salray应该在range4000和10000 ORA-06512:at&#34; HR.SECURE_EMPLOYEES_SAL_RANGE&#34;,第14行ORA-04088:执行触发期间的错误&#39; HR.SECURE_EMPLOYEES_SAL_RANGE&#39; 无法处理表EMPLOYEES的行。
答案 0 :(得分:2)
触发器没有参数。
我的猜测是你想要一个行级触发器,而不是你在这里的语句级触发器。我猜你在行级触发器中想要使用:new.job_id
来查找jobs
表中的数据
create or replace TRIGGER secure_employees_sal_range
BEFORE INSERT OR UPDATE OF salary,job_id ON employees
FOR EACH ROW
DECLARE
p_min_sal Integer;
p_max_sal Integer;
BEGIN
--check_salaray_range(employee_id,job_id,salary);
select min_salary, max_salary
into p_min_sal, p_max_sal
from jobs
where job_id = :new.job_id;
if p_salary < p_min_sal OR p_salary > p_max_sal THEN
RAISE_APPLICATION_ERROR (-20225,
'Salary should in range' || p_min_sal || ' and ' || p_max_sal);
END IF;
END secure_employees_sal_range;
我假设这是一个家庭作业。实际上,在多用户系统中,这种触发器存在各种问题。例如,有人可能在您修改jobs
表的同时修改employees
表,并且两个事务都不能看到另一个的未提交的工作。即使您在jobs
上有相应的触发器,也完全有可能以违反您尝试执行的范围规则的已保存数据结束。
作为一般规则,我还建议局部变量使用l_
前缀而不是p_
,它通常表示参数。我通常也会建议您使用锚定类型。所以
l_min_sal jobs.min_salary%type;
这样,如果jobs
表中的数据类型发生变化,您的代码就会自动适应。