ORACLE pl/sql自定义函数、存储过程 0326

版权声明:转载请注明出处,欢迎讨论,共同进步,QQ:1051780721 https://blog.csdn.net/ACM2017/article/details/88812739

ORACLE pl/sql自定义函数、存储过程

2019-03-26

实验六、七 PL/SQL编程(2)

目的和要求:

1.​ 掌握存储过程和函数的使用
2.​ 掌握游标的使用
3.​ 掌握程序包的使用
4.​ 掌握触发器的使用

实验内容:

SCOTT用户拥有DEPT、EMP、SALGRADE表对象,其中,
DEPT是部门信息表,包括:部门编号、部门名称、部门地址三个属性,即DEPT(DEPTNO,DNAME,LOC)。
EMP是员工信息表,包括:员工编号、员工姓名、职位、上级领导、雇用时间、薪金、佣金、所属部门编号八个属性,即EMP(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)。
SALGRADE是工资等级表,包括:工资等级、最低工资、最高工资三个属性,即SALGRADE(GRADE,LOSAL,HISAL)。

set serveroutput on
describe emp;
1.​ 使用异常编写一个PL/SQL程序来检查职工号为7369的职工的奖金,如果没有奖金的话则显示出错信息。

参考答案(仅为参考,有些并不可以直接执行):
declare
comm_error exception;
v_comm emp.comm%type;
begin
select comm into v_comm from emp where empno=‘7369’;
if v_comm=0 or v_comm is null then
raise comm_error;
end if;
exception
when NO_DATA_FOUND then
dbms_output.put_line(‘无7369职工!’);
when comm_error then
dbms_output.put_line(‘无佣金!’);
end;
/体会预定义异常、非预定义异常、用户自定义异常的使用。

declare
 comm_error exception;
 v_comm emp.comm%type;
begin
 select comm into v_comm from emp where empno=7369;
 if v_comm=0 or v_comm is null then
  raise comm_error;
 end if;

 exception
 when NO_DATA_FOUND then
  dbms_output.put_line('查无此人');
 when comm_error then
  dbms_output.put_line('无奖金');

end;
2.​ 编写一个函数来找出职工工资数额的信息,该函数还可以接受职工的号码。

create or replace function return_sal (eno scott.emp.empno%type)
return number
is
v_sal scott.emp.sal%type;
begin
select sal into v_sal from scott.emp where empno=eno;
return v_sal;
exception
when NO_DATA_FOUND then
dbms_output.put_line(‘无此职工!’);
end;
/
调用
declare
v_sal number(7,2);
begin
v_sal :=return_sal(7369);
dbms_output.put_line(v_sal);
end;
/

create or replace function return_sal (eno emp.empno%type)
return number
is
v_sal emp.sal%type;
begin
select sal into v_sal from emp where empno=eno;
return v_sal;
exception
when NO_DATA_FOUND then
dbms_output.put_line('无此职工!');
end;
/
调用
declare
v_sal number(7,2);
begin
v_sal :=return_sal(7369);
dbms_output.put_line(v_sal);
end;
/
3.​ 编写一个函数来找出职工的经理信息,该函数还可以接受职工的姓名。
create or replace function return_mgr (nowname emp.ename%type)
return number
is
v_mgr emp.mgr%type;
begin
select mgr into v_mgr from emp where ename=nowname;
return v_mgr;
exception
when NO_DATA_FOUND then
dbms_output.put_line('无此职工!');
end;
/
调用
declare
v_mgr number(4);
begin
v_mgr :=return_mgr('CLARK');
dbms_output.put_line(v_mgr);
end;
/
4.​ 编写一个函数,该函数可以根据接受职工的号码。来返回ENAME、SAL、DEPTNO信息。

create or replace function ret_info(empno emp.empno%type, sal out emp.sal%type, deptno out emp.deptno%type)
return emp.ename%type
is
v_name emp.ename%type;
begin
select ename, sal, deptno into v_name, sal, deptno from emp where empno=empno;
return v_name;
end ;
/
调用
declare
v_name emp.ename%type;
v_sal emp.sal%type;
v_deptno emp.deptno%type;
begin
v_name:=ret_info(&empno, v_sal, v_deptno);
dbms_output.put_line(v_name||v_deptno||v_sal);
end;

//示例程序中,line6,where empno=empno:实际返回的行数超出请求的行数。更名即可。
create or replace function ret_info(empo emp.empno%type, sal out emp.sal%type, deptno out emp.deptno%type)
return emp.ename%type
is
v_name emp.ename%type;
begin
select ename, sal, deptno into v_name, sal, deptno from emp where empno=empo;
return v_name;
end ;
/
5.​ /

接4,调用函数

declare
v_name emp.ename%type;
v_sal emp.sal%type;
v_deptno emp.deptno%type;
v_eno emp.empno%type;
begin
v_eno:=&v_eno;
v_name:=ret_info(v_eno, v_sal, v_deptno);
dbms_output.put_line(v_name||' '||v_deptno||' '||v_sal);
end;
/

在这里插入图片描述

6.​ 编写一个函数,该函数可以根据接受的职工姓名,来确定该职工的年收入信息。如果有两个或以上重名职工的话将出现错误信息。
//注意输入字符串的格式:'###'

create or replace function return_annualSalary(nowname emp.ename%type)
return number
is
v_sal emp.sal%type;
begin
select sal into v_sal from emp where ename=nowname;
return 12*v_sal;
exception
when NO_DATA_FOUND then
dbms_output.put_line('无此职工!');
end;
/
调用
declare
v_sal emp.sal%type;
begin
v_sal:=return_annualSalary(&nowname);
dbms_output.put_line(v_sal);
end;
/

Wrong
Right

7.​ 编写一个存储过程来显示出DEPT表的所有信息。
create or replace procedure show_dept is
begin
  dbms_output.put_line('---------------------------------------');
  for dept_i in (select * from dept)
    loop
      dbms_output.put_line(dept_i.deptno||' '||dept_i.dname||' '||dept_i.loc);
    end loop;
  dbms_output.put_line('---------------------------------------');
end;
/

begin
  show_dept;
end;
/

在这里插入图片描述

8.​ 编写一个存储过程来显示出EMP表信息,而且该过程可以接受DEPTNO列的数据。

create or replace procedure show_emp (deptno in emp.deptno%type)
is
cursor emp_cursor is select * from emp;
begin
for r in emp_cursor loop
dbms_output.put(r.empno || ‘’);
dbms_output.put(r.ename || ‘’);
dbms_otuput.put(r.job || ‘’);
dbms_output.put(r.mgr || ‘’);
dbms_output.put(r.hiredate || ‘’);
dbms_output.put(r.sal || ‘’);
dbms_output.put(r.comm || ‘’);
dbms_output.put_line(r.deptno);
end loop;
end;
/
过程调用
set serveroutput on
declare
deptno emp.deptno%type:=7369;
begin
show_emp(deptno);
end;
/

create or replace procedure show_emp (dno in emp.deptno%type)
is
  cursor emp_cursor is select * from emp where emp.deptno=dno;
begin
  dbms_output.put_line('---------------------------------------');
  for r in emp_cursor loop
    dbms_output.put_line(r.empno || ''|| r.ename || ''||r.job || ''||r.mgr || ''||r.hiredate || ''||r.sal || ''||r.comm || ''||r.deptno);
  end loop;
  dbms_output.put_line('---------------------------------------');
end;
/

begin
  show_emp(10);
end;
/

在这里插入图片描述
…空格…
在这里插入图片描述

9.​ 根据工作类别,编写一个存储过程来找出工资数额最高的职工信息。

(此题目应该理解为,根据部门编号,找出每个部门中工资数额最高的职工信息,需要使用游标实现)
/

10.​ 编写一个触发器,它能够自动计算所有职工的总收入,并且在DEPT表中的一个专门的列中保存它们(在DEPT表中增加一个名为TOT_SAL的列)。

alter table DEPT
add (TOT_SAL number);
CREATE OR REPLACE TRIGGER tr_add_sal
After UPDATE or INSERT or DELETE
ON emp
Is
Cursor c1 is select distinct deptno from emp;
v_tot_sal emp.sal%Type;
Begin
For i in c1 loop
Select sum(sal) into v_tot_sal from emp where deptno=i.deptno;
Update dept set tot_sal=v_tot_sal where deptno= i.deptno;
End loop;
End;

11.​ 在EMP_DEPT视图上编写一个触发器,该触发器可以检查SALGRADE表中的收入范围,如果任何一个更新或者插入的值超出9999的话则出现错误信息。

猜你喜欢

转载自blog.csdn.net/ACM2017/article/details/88812739