创建触发器,当修改雇员的工资级别时,如果新的工资级别不在该雇员工作(job_id)的最低最高工资级别(jobs 表的min_lvl, max_lvl)范围内,将该雇员的工资级别设置为该雇员工作(job_id)的最低工资级别(min_lvl)。
时间: 2024-05-05 07:19:12 浏览: 170
好的,针对您的问题,可以使用如下的 SQL 语句创建触发器:
```
CREATE TRIGGER update_employee_salary
BEFORE UPDATE OF salary ON employees
FOR EACH ROW
BEGIN
DECLARE job_min_lvl INT;
DECLARE job_max_lvl INT;
SELECT min_lvl, max_lvl INTO job_min_lvl, job_max_lvl
FROM jobs WHERE job_id = NEW.job_id;
IF NEW.salary < job_min_lvl OR NEW.salary > job_max_lvl THEN
SET NEW.salary = job_min_lvl;
END IF;
END;
```
该触发器会在每次执行雇员薪资更新操作前自动触发,并根据雇员所在工作的最高、最低工资级别限制来自动更新雇员的薪资。如果更新后的薪资不在工作级别范围内,则会被更新为工作的最低工资级别。
相关问题
利用游标,对scott方案下emp表中某个部门的雇员涨工资,部门号及涨工资比例均由手动输入。如果输入部门号不存在,或涨工资比例大于50%,均捕获异常输出相应出错提示信息。 2. 编写存储过程,要求输入部门编号,输出scott.emp表中该部门所有职工的职工编号、姓名、工作岗位。 3. 编写函数,要求将scott.emp表中低于平均工资的职工工资加上200,并返回修改了工资的总人数。 4. 编写以下触发器,分别实现不同的操作: (1) 在执行删除操作时触发,输出“Delete finished!”; (2) 在创建表之前提示:“请确认你的权限”; (3) 为system用户创建一个触发器,记录登录用户的用户名和登录时间(由Logon事件触发)。
好的,以下是每个问题的代码示例:
1. 利用游标,对scott方案下emp表中某个部门的雇员涨工资,部门号及涨工资比例均由手动输入。如果输入部门号不存在,或涨工资比例大于50%,均捕获异常输出相应出错提示信息。
```
DECLARE
v_deptno NUMBER;
v_increase NUMBER;
v_count NUMBER := 0;
CURSOR c_emp IS
SELECT * FROM emp WHERE deptno = v_deptno;
BEGIN
-- 获取部门号和涨工资比例
v_deptno := &deptno;
v_increase := &increase;
-- 判断部门号是否存在
SELECT COUNT(*) INTO v_count FROM dept WHERE deptno = v_deptno;
IF v_count = 0 THEN
RAISE_APPLICATION_ERROR(-20001, '该部门号不存在!');
END IF;
-- 判断涨工资比例是否大于50%
IF v_increase > 0.5 THEN
RAISE_APPLICATION_ERROR(-20002, '涨工资比例不能超过50%!');
END IF;
-- 遍历游标并涨工资
FOR emp_rec IN c_emp LOOP
UPDATE emp SET sal = sal * (1 + v_increase) WHERE empno = emp_rec.empno;
DBMS_OUTPUT.PUT_LINE('员工 ' || emp_rec.ename || ' 的工资已涨至 ' || emp_rec.sal * (1 + v_increase));
END LOOP;
DBMS_OUTPUT.PUT_LINE('涨工资操作已完成!');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLCODE || ' - ' || SQLERRM);
END;
```
2. 编写存储过程,要求输入部门编号,输出scott.emp表中该部门所有职工的职工编号、姓名、工作岗位。
```
CREATE OR REPLACE PROCEDURE get_emp_by_deptno (p_deptno IN NUMBER) AS
BEGIN
FOR emp_rec IN (SELECT empno, ename, job FROM emp WHERE deptno = p_deptno) LOOP
DBMS_OUTPUT.PUT_LINE('员工编号:' || emp_rec.empno || ',姓名:' || emp_rec.ename || ',工作岗位:' || emp_rec.job);
END LOOP;
END;
```
3. 编写函数,要求将scott.emp表中低于平均工资的职工工资加上200,并返回修改了工资的总人数。
```
CREATE OR REPLACE FUNCTION increase_salary RETURN NUMBER AS
v_avg_salary NUMBER;
v_count NUMBER := 0;
BEGIN
-- 计算平均工资
SELECT AVG(sal) INTO v_avg_salary FROM emp;
-- 遍历雇员,修改工资
FOR emp_rec IN (SELECT * FROM emp WHERE sal < v_avg_salary) LOOP
UPDATE emp SET sal = sal + 200 WHERE empno = emp_rec.empno;
v_count := v_count + 1;
END LOOP;
RETURN v_count;
END;
```
4. 编写以下触发器,分别实现不同的操作:
(1)在执行删除操作时触发,输出“Delete finished!”;
```
CREATE OR REPLACE TRIGGER trg_delete_emp
AFTER DELETE ON emp
BEGIN
DBMS_OUTPUT.PUT_LINE('Delete finished!');
END;
```
(2)在创建表之前提示:“请确认你的权限”;
```
CREATE OR REPLACE TRIGGER trg_create_table
BEFORE CREATE ON DATABASE
DECLARE
v_user VARCHAR2(30);
BEGIN
-- 获取当前用户
SELECT USER INTO v_user FROM dual;
IF v_user <> 'DBA' THEN
RAISE_APPLICATION_ERROR(-20001, '请确认你的权限!');
END IF;
END;
```
(3)为system用户创建一个触发器,记录登录用户的用户名和登录时间(由Logon事件触发)。
```
CREATE OR REPLACE TRIGGER trg_system_logon
AFTER LOGON ON database
WHEN (USER = 'SYSTEM')
DECLARE
v_username VARCHAR2(30);
BEGIN
-- 获取登录用户名
SELECT USER INTO v_username FROM dual;
-- 记录登录信息
INSERT INTO system_logon_history (username, logon_time) VALUES (v_username, SYSDATE);
END;
```
适用于EMP表的事务规则如下所示。给下面的每个规则设置各自的触发器。 【规则1】工作岗位不为SALESMAN的雇员不能有奖金(即,将其奖金列设置为0)。(这个限制对于已经在表EMP中存在的记录无效,它仅能约束对雇员表进行的插入雇员和更新雇员的操作)。 请拟定插入语句(自行拟定)和更新语句(将雇员号为251的员工的奖金更新为1000)进行测试,验证触发器是否成功触发! 【规则2】工资只能增长,不能下降,若更新后的工资低于之前的工资则保持原工资,并提示“工资只能增长,不能下降!”。 测试:雇员号为251的员工的当前工资为10000,将他的工资减少到8500,测试你的答案。
触发器的创建如下:
【规则1】触发器:
```
CREATE TRIGGER no_bonus
BEFORE UPDATE OR INSERT ON emp
FOR EACH ROW
BEGIN
IF NEW.job != 'SALESMAN' AND NEW.comm IS NOT NULL THEN
SET NEW.comm = 0;
END IF;
END;
```
【规则2】触发器:
```
CREATE TRIGGER no_salary_decrease
BEFORE UPDATE ON emp
FOR EACH ROW
BEGIN
IF NEW.sal < OLD.sal THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '工资只能增长,不能下降!';
SET NEW.sal = OLD.sal;
END IF;
END;
```
测试语句如下:
```
-- 插入语句
INSERT INTO emp(empno, ename, job, sal, deptno, comm)
VALUES(8001, 'Test1', 'CLERK', 2000, 10, 1000);
-- 更新语句
UPDATE emp SET comm = 1000 WHERE empno = 251;
-- 工资下降测试语句
UPDATE emp SET sal = 8500 WHERE empno = 251;
```
执行后,如果触发器成功触发,则在更新或插入时,工作岗位不为SALESMAN的员工将不会有奖金(奖金列会被设置为0),而且工资只能增长,不能下降。如果工资下降,则会提示“工资只能增长,不能下降!”,并且将工资恢复到之前的值。
阅读全文