Oracle 11g数据库基础教程(第2版)-课后习题-第十章

--1创建一个存储过程,以员工号为参数,输出该员工的工资。
set serveroutput on
create or replace procedure show(p_no emp.empno%type)
as
	v_sal emp.sal%type;
begin
	select sal into v_sal from emp where empno=p_no;
	dbms_output.put_line(v_sal);
exception
	when no_data_found then 
	dbms_output.put_line('there is not such employee');
	end;
/
--调用过程
begin
	show(2010);
end;
/

--2 创建一个存储过程,以员工号为参数,
-- 修改该员工的工资。若该员工属于10号部门,
-- 则工资增加140元;若属于20号部门,则工资增加200元;
-- 若属于30号部门,则工资增加250元;若属于其他部门,则工资增长300元。
set serveroutput on
create or replace procedure show2(p_no emp.empno%type)
as
	v_dno emp.deptno%type;
	v_inc number;
begin
	select deptno into v_dno from emp where empno=p_no;
	case v_dno
		when 10 then v_inc:=140;
		when 20 then v_inc:=200;
		when 30 then v_inc:=250;
		else v_inc:=300;
	end case;
		update emp set sal=sal+v_inc where empno=p_no;
	exception
		when no_data_found then
		dbms_output.put_line('there is not such an employees');
	end;
/
--在调用前后查看一下
select sal,empno,deptno from emp where empno='2010';
begin
	show2(2010);
end;
/
select sal,empno,deptno from emp where empno='2010';
--3 创建一个函数,以员工号为参数,返回该员工的工资。
set serveroutput on 
create or replace function retsal(p_no emp.empno%type) return emp.sal%type
	as
		v_sal emp.sal%type;
	begin
		select sal into v_sal from emp where p_no = empno;
		return v_sal;
	exception
		when no_data_found then
		dbms_output.put_line('there is not such an employees');
end;
/
--调用此函数
begin
	dbms_output.put_line('This sal is:' || retsal(2010));
end;
/
--4 创建一个函数,以员工号为参数,返回该员工所在部门的平均工资
set serveroutput on
create or replace function retavgsal(p_no emp.empno%type)
	return emp.sal%type
as
	v_dno emp.deptno%type;
	v_avgsal emp.sal%type;
begin
	select deptno into v_dno from emp where p_no = empno;
	select avg(sal) into v_avgsal from emp where v_dno = deptno;
	return v_avgsal;
	exception
	when no_data_found then
		dbms_output.put_line('there is not such an employees');
	end;
/
--调用此函数
begin
	dbms_output.put_line(retavgsal(7654));
end;
/
--5.创建一个包,包中包含一个函数和一个过程。函数以部门号为参数,返回该部门员工的最高工;过程以部门号为参数,输出该部门中工资最高的员工名,员工号
on serveroutput on
--创建包体
create or replace package pak_emp
as
function func_maxsal(p_d emp.deptno%type) return emp.sal%type;
procedure pro_dep(p_dep emp.deptno%type);
end pak_emp;
/
--
create or replace package body pak_emp
as
	function func_maxsal(p_d emp.deptno%type) return emp.sal%type
as
	v_maxsal emp.sal%type;
begin
	select max(sal) into v_maxsal from emp
	where deptno=p_d;
	return v_maxsal;
end func_maxsal;

procedure pro_dep(p_dep emp.deptno%type)
as
	v_ename emp.ename%type;
	v_empno emp.empno%type;
	maxsal emp.sal%type;
begin
	select max(sal) into maxsal from emp
	where deptno=p_dep;
	select ename,empno into v_ename,v_empno from emp where deptno=p_dep and sal=maxsal;
	dbms_output.put_line(v_ename || ' ' || v_empno || ' ' || maxsal);
exception
	when too_many_rows then
	dbms_output.put_line('返回多行数据!');
end pro_dep;
end pak_emp;
/

begin
pak_emp.pro_dep(30);
dbms_output.put_line(pak_emp.func_maxsal(30));
end;
/
--查询一下部门
--6.创建一个包,包中包含一个过程和一个游标,游标返回所有员工的信息;存储过程实现每次输出游标中的5条记录
create or replace package pkg_showemp
as
	cursor c_emp is select * from emp;
	procedure show_fiveemp;
end pkg_showemp;
/
create or replace package body pkg_showemp
as
	procedure show_fiveemp
as
	v_emp c_emp%rowtype;
begin
	if not c_emp%isopen then
	open c_emp;
	end if;
	for i in 1..5 loop
		fetch c_emp into v_emp;
			if c_emp%notfound then
				close c_emp;
			exit;
			end if;
		dbms_output.put_line(v_emp.empno || ' ' || v_emp.ename);
	end loop;
end show_fiveemp;
end pkg_showemp;
/
begin
	pkg_showemp.show_fiveemp;
end;
/

--7在employees表上创建一个触发器,保证每天8:00-17:00之外的时间禁止对该表进行DML操作
create or replace trigger trg_emp
	before insert or update or delete on emp
	begin
		if to_char(sysdate,'HH24:MI') not between '08:00' and '17:00'
		then
		raise_application_error(-2000,'此时间,不允许修改emp表');
	end if;
	end;
/
--禁用指定触发器
alter trigger trg_emp disable;
--8 在employees表上创建一个触发器,当插入、删除或修改员工信息时,
--统计各个部门的人数及平均工资,并输出。
set serveroutput on
create or replace trigger tr8
after insert or update or delete of sal on emp
	declare
		cursor c_dept is select deptno,avg(sal)avgsal,count(*)num from emp group by deptno;
		v c_dept%rowtype;
	begin
		for v in c_dept loop
		dbms_output.put_line(v.deptno || ' ' || v.avgsal || ' ' || v.num);
	end loop;
end;
/
--更新数据,触发触发器--desc降序
update emp set sal=900 where empno=7369;
--10.创建一个存储过程,以一个整数为参数,输出工资最高的前几个(参数指定)员工的信息
set serveroutput on
create or replace procedure pro_emp(p number)
as
	cursor v_sal is select * from emp where sal is not null and rownum <= p order by sal desc;
begin
	for v in v_sal loop
	dbms_output.put_line(v.empno || ' '  || v.sal ||' ' || v.deptno);
end loop;
end pro_emp;
/
--测试
begin
	pro_emp(5);
end;

你可能感兴趣的:(Oracle,11g)