SQL 触发限制用户更新会计工资
SQL trigger to restrict user to update salary of accountant
我必须创建一个触发器来限制任何用户更新 job_title
是会计的员工的工资。例如:如果有人使用以下命令更新工资:
UPDATE Employees
SET Salary = 11000
WHERE job_id = '101';
然后它首先检查与 101 的 job_id
关联的 job_title
是否是会计师。如果是,则抛出一条错误消息,指出您无法更新会计师的薪水。这是我的触发代码,但它无法正常工作。
CREATE OR REPLACE TRIGGER salaryrestruction
BEFORE UPDATE ON employees
DECLARE job_title employees.job_title%type;
BEGIN
IF UPDATING('SALARY') AND JOB_TITLE='accountant'
THEN RAISE_APPLICATION_ERROR
(-20501,'You cannot update SALARY of accountant');
END IF;
END;
这是我 table 的数据:
EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_TITLE SALARY COMMISSION_PCT
----------- -------------------- ------------------------- ------------------------- -------------------- --------- -------------------- ---------- --------------
102 Randall Zlotkey zlotkey@gmail.com 13675464345 22-MAY-02 Manager 20000
103 John Bernstein bernsteinex@gmail.com 12876454345 23-JUN-03 Accountant 10000 .2
104 Peter Sully sully@gmail.com 13187754345 01-FEB-03 Executive 8000 .4
105 Alberto Hall hall@gmail.com 10000354345 06-APR-05 Human Resources 4500
106 Karen Olsen olsen@gmail.com 13144444345 13-MAY-05 Marketing 10000 .1
107 Peter Christopher christopher@gmail.com 13456754345 13-MAY-06 Administration 12000 .2
101 Lex De Haan lex@gmail.com 13124354345 19-JAN-01 Accountant 9000 .3
只有 row-level 触发器才能看到正在更新的每个职位。然后,您可以在触发器 body 中使用 :new.job_title
或在 header 中将其引用为 new.job_title
.
如果您在 header 中使用 when
条件,则无需在触发器 body 中检查它。您也不需要检查触发器是否在 before update
触发器中更新。
但是,如果这是您的业务规则,您确实需要检查薪水是否正在更改。 (我没有针对 salary 之前为 null 或正在更新为 null 的可能性进行编码 - 如果可能的话,那么您将需要多行代码。)
create or replace trigger salaryrestriction
before update on employees for each row
when (new.job_title = 'Accountant')
begin
if :new.salary <> :old.salary then
raise_application_error(-20501, 'You cannot update SALARY of accountant');
end if;
end;
我们不需要用大写字母编写代码,因为它不是 COBOL,也不是 1974 年。
我必须创建一个触发器来限制任何用户更新 job_title
是会计的员工的工资。例如:如果有人使用以下命令更新工资:
UPDATE Employees
SET Salary = 11000
WHERE job_id = '101';
然后它首先检查与 101 的 job_id
关联的 job_title
是否是会计师。如果是,则抛出一条错误消息,指出您无法更新会计师的薪水。这是我的触发代码,但它无法正常工作。
CREATE OR REPLACE TRIGGER salaryrestruction
BEFORE UPDATE ON employees
DECLARE job_title employees.job_title%type;
BEGIN
IF UPDATING('SALARY') AND JOB_TITLE='accountant'
THEN RAISE_APPLICATION_ERROR
(-20501,'You cannot update SALARY of accountant');
END IF;
END;
这是我 table 的数据:
EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_TITLE SALARY COMMISSION_PCT
----------- -------------------- ------------------------- ------------------------- -------------------- --------- -------------------- ---------- --------------
102 Randall Zlotkey zlotkey@gmail.com 13675464345 22-MAY-02 Manager 20000
103 John Bernstein bernsteinex@gmail.com 12876454345 23-JUN-03 Accountant 10000 .2
104 Peter Sully sully@gmail.com 13187754345 01-FEB-03 Executive 8000 .4
105 Alberto Hall hall@gmail.com 10000354345 06-APR-05 Human Resources 4500
106 Karen Olsen olsen@gmail.com 13144444345 13-MAY-05 Marketing 10000 .1
107 Peter Christopher christopher@gmail.com 13456754345 13-MAY-06 Administration 12000 .2
101 Lex De Haan lex@gmail.com 13124354345 19-JAN-01 Accountant 9000 .3
只有 row-level 触发器才能看到正在更新的每个职位。然后,您可以在触发器 body 中使用 :new.job_title
或在 header 中将其引用为 new.job_title
.
如果您在 header 中使用 when
条件,则无需在触发器 body 中检查它。您也不需要检查触发器是否在 before update
触发器中更新。
但是,如果这是您的业务规则,您确实需要检查薪水是否正在更改。 (我没有针对 salary 之前为 null 或正在更新为 null 的可能性进行编码 - 如果可能的话,那么您将需要多行代码。)
create or replace trigger salaryrestriction
before update on employees for each row
when (new.job_title = 'Accountant')
begin
if :new.salary <> :old.salary then
raise_application_error(-20501, 'You cannot update SALARY of accountant');
end if;
end;
我们不需要用大写字母编写代码,因为它不是 COBOL,也不是 1974 年。