Oracle Validation Trigger用于范围检查

时间:2015-06-30 21:27:15

标签: oracle oracle11g triggers

可能会提出类似的问题,如果是,请分享链接。

必需:

每当创建或更新新记录时,都需要验证该人的工资是否符合工作范围。

  • 包含job_id和最小工资范围的工作表。
  • 员工表 with employee_id,name,job_id和salary。

以下是触发器,

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的行。

1 个答案:

答案 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表中的数据类型发生变化,您的代码就会自动适应。