我是靠谱客的博主 爱听歌大白,这篇文章主要介绍实验6触发器,现在分享给大家,希望可以做个参考。

1.函数定义和使用

  1. 创建一个为单个员工进行加薪的函数. 该函数有两个IN的参数, 员工编号和加薪幅度, 并返回加薪后的总薪水.
复制代码
1
2
3
4
5
6
7
8
9
10
CREATE FUNCTION add_sal (emp_number IN NUMBER,a IN NUMBER) RETURN NUMBER AS newsal emp.sal%TYPE; BEGIN UPDATE emp SET sal = sal*(1+a) WHERE empno=emp_number; SELECT sal INTO newsal FROM emp WHERE empno = emp_number; RETURN newsal; END add_sal; /

输出:

复制代码
1
2
3
4
5
6
set serveroutput on declare BEGIN DBMS_OUTPUT.PUT_LINE(add_sal(7900,0.1)); END; /

2.创建函数avg_sal,根据部门编号计算该部门所有职工的平均工资

复制代码
1
2
3
4
5
6
7
8
CREATE FUNCTION avgsal(dept_number IN NUMBER) RETURN NUMBER AS sal_avg emp.sal%TYPE; BEGIN SELECT AVG(sal) INTO sal_avg FROM emp WHERE deptno = dept_number; RETURN sal_avg; END avgsal; / SELECT avgsal(20) FROM dual

3.创建一个存储过程,并定义3个in模式的变量,然后将这3个变量的值插入到emp表empno,ename,job列中

复制代码
1
2
3
4
5
6
7
8
9
10
11
CREATE OR REPLACE PROCEDURE a_insert (emp_number IN emp.empno%TYPE, emp_name IN emp.ename%TYPE, emp_job IN emp.job%TYPE) AS BEGIN INSERT INTO emp(empno,ename,job) VALUES(emp_number,emp_name,emp_job); END a_insert; / EXEC a_insert(1000,'Fang','carry'); SELECT empno,ename,job FROM emp WHERE empno=1000;

 

4.创建存储过程,根据员工编号查询员工的姓名及工资,使用in参数传入员工编号,使用out参数传出姓名及工资。并对未查询到的数据进行错误处理。?????????????????????????????????????????????

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE PROCEDURE select_emp (emp_number IN NUMBER,emp_name OUT VARCHAR2,emp_sal OUT NUMBER) AS BEGIN SELECT ename,sal INTO emp_name,emp_sal FROM emp WHERE empno=emp_number; END select_emp; / (DROP PROCEDURE select_emp;) VARIABLE name VARCHAR2(10); VARIABLE sal NUMBER; EXEC select_emp(7900,:name,:sal); PRINT name; PRINT sal;

5.创建存储过程为员工涨工资,有部门的员工每人涨500,没有部门的员工每人涨100。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CREATE PROCEDURE addsal (emp_number IN emp.empno%TYPE) AS a NUMBER(10); BEGIN a:=0; SELECT deptno INTO a FROM emp WHERE empno=emp_number; IF a=0 THEN UPDATE emp SET sal=sal+100 WHERE empno=emp_number; ELSE UPDATE emp SET sal=sal+500 WHERE empno=emp_number; END IF; END addsal; / SELECT sal FROM emp WHERE empno=7900; EXEC addsal(7900); SELECT sal FROM emp WHERE empno=7900;

6.创建一个事前触发器,当对emp表的sal列进行修改时,将员工号、加薪前和加薪后的薪资存入temp表中(temp表需要事先建立)。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE TABLE temp( content VARCHAR2(100), rtime TIMESTAMP ); CREATE TRIGGER update_emp AFTER UPDATE ON emp FOR EACH ROW BEGIN INSERT INTO temp VALUES('执行了更新操作,empno='||:OLD.empno||'更新前的工资 sal='||:OLD.sal||'new_sal='||:new.sal,SYSDATE); END update_emp; / UPDATE emp SET sal = 1595 WHERE empno=7900; SELECT * FROM temp;

7.创建一个事前触发器tri_dept,该触发器在insert、update和delete事件下都可以被触发,并且操作的数据对象是emp表。然后要求在触发器执行时输出对emp表所做的具体操作。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
create or replace trigger tri_dept before insert or update or delete on dept --创建触发器,当dept表发生插入,修改,删除操作时引起该触发器执行 declare var_tag varchar2(10);--声明一个变量,存储对dept表执行的操作类型 begin if inserting then --当触发事件是INSERT时 var_tag := '插入';--标识插入操作 elsif updating then --当触发事件是UPDATE时 var_tag := '修改';--标识修改操作 elsif deleting then--当触发事件是DELETE时 var_tag := '删除';--标识删除操作 end if; insert into dept_log values(var_tag,sysdate);--向日志表中插入对dept表的操作信息 end tri_dept;

8.创建一个事前行触发器。对修改雇员工资的操作进行合法性检查:没有单位(部门号为空)的员工不能修改工资,修改后的工资要大于修改前的工资;工资增量不能超过原工资的20%,如果违反合法性检查,将输出错误信息。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
create or replace trigger judge_emp before update of sal on emp for each row begin IF :old.deptno is null then dbms_output.put_line(:old.empno||'没有部门,不能修改工资'); ELSIF :new.sal<:old.sal then dbms_output.put_line(:old.empno||'修改后的工资应该大于修改前的工资'); ELSIF :new.sal-:old.sal>=:old.sal*0.2 then dbms_output.put_line(:old.empno||'工资增量不能超过原工资的20%'); END IF; end judge_emp; / update scott.emp set sal = sal-100 where deptno is null; update scott.emp set sal = sal*1.5 where deptno is null;

9.创建事后触发器,当插入或删除的雇员记录属于30号部门时,输出操作种类和雇员号。输出格式如下所示:

插入30号部门一个记录,雇员号为:18

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
create or replace trigger aft_emp after insert or update or delete on emp for each row when(old.deptno=30) begin if inserting or updating then dbms_output.put_line('插入30号部门的一个记录,雇员号为:'||:new.empno); elsif deleting then dbms_output.put_line('删除30号部门的一个记录,雇员号为:'||:old.empno); end if; end aft_emp; / INSERT INTO scott.emp(empno,ename,deptno) VALUES(18,'lihao',30); DELETE FROM emp WHERE empno=18;

10.创建一个程序包的“规范”pack_emp,首先在该程序包中声明一个可以获取指定部门的平均工资的函数,然后再声明一个可以实现按照指定比例上调指定职务的工资的存储过程。创建程序包pack_emp的主体,在该主体中实现对应“规范”中声明的函数和存储过程。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
CREATE PACKAGE pack_emp AS FUNCTION avq_sal2(dno IN scott.emp.deptno%TYPE) RETURN scott.emp.sal%TYPE; PROCEDURE rise_sal2(ejob IN scott.emp.job%TYPE, range IN number ); END pack_emp; / CREATE OR REPLACE PACKAGE BODY pack_emp IS FUNCTION avq_sal2(dno IN scott.emp.deptno%TYPE) RETURN scott.emp.sal%TYPE IS salary scott.emp.sal%TYPE; BEGIN SELECT avg(sal) INTO salary FROM scott.emp WHERE deptno=dno; RETURN salary; EXCEPTION WHEN NO_DATA_FOUND THEN dbms_output.put_line('未找到相应的部门编号'); RETURN 0; END avq_sal2; PROCEDURE rise_sal2(ejob IN scott.emp.job%TYPE, range IN number ) IS salary scott.emp.sal%TYPE; BEGIN update scott.emp set sal = sal*(1+range) where job=ejob; EXCEPTION WHEN NO_DATA_FOUND THEN dbms_output.put_line('未找到相应的工作岗位'); END rise_sal2; END pack_emp ; /

 

最后

以上就是爱听歌大白最近收集整理的关于实验6触发器的全部内容,更多相关实验6触发器内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部