Oracle——存储过程和函数练习题
Posted Xiu Yan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle——存储过程和函数练习题相关的知识,希望对你有一定的参考价值。
文章目录
存储过程:
1、把数据表 fruits 中价格最低的两个水果的名称设置为“打折水果”
fruits 表结构可参考右侧链接:Oracle——PL/SQL 块结构练习题
set serveroutput on; -- 设置环境变量serveroutput为打开状态,使得pl/sql程序能够在SQL*plus中输出结果
-- 创建存储过程
create or replace procedure fruits_prc
as
begin
update fruits set f_name = '打折水果' where f_id in(
select f_id from (
select * from fruits order by f_price asc
)
where rownum <= 2
);
commit;
end;
/
exec fruits_prc --执行
查看结果:
select f_id, f_name from (
select * from fruits order by f_price asc
)
where rownum <= 2;
2、创建一个存储过程用来统计表 sch 中的记录数和 sch 表中 id 的和
-- 创建表
create table sch(
id number(8) primary key,
name varchar2(20) not null,
class varchar2(20) not null
);
-- 插入数据
insert into sch values(1, 'xiaoming', 'class1');
insert into sch values(2, 'xiaojun', 'class2');
--SQL%FOUND 判断SQL语句是否成功执行。当有作用行时则成功执行为true,否则为false。
create or replace procedure count_sch
as
v_count number(5);
v_sum number(5);
begin
select count(*) into v_count from sch;
select sum(id) into v_sum from sch;
if sql%found then
dbms_output.put_line('记录数为:'||v_count);
dbms_output.put_line('id和为:'||v_sum);
end if;
end;
/
exec count_sch; -- 执行过程
3、指定学生姓名,查询该生的总学分,使用一个输入参数,一个输出参数
已知学生表(XS)存储信息:学号(Sno,int),姓名(Sname,char(10) ),总学分(Credit,int)。
-- 创建表
create table XS(
xno number(10) primary key not null,
sname varchar2(10),
credit number(10)
);
-- 插入数据
insert into XS values(1, 'stu01', 200);
insert into XS values(2, 'stu02', 300);
insert into XS values(3, 'stu03', 120);
不使用输出参数,直接方式:
-- 创建存储过程
create or replace procedure student_credit
as
v_sname XS.sname %TYPE := &v_sname;
v_credit number(5);
begin
select credit into v_credit from XS where sname = v_sname;
if sql%found then
dbms_output.put_line('学生'|| v_sname ||'的总学分为:'||v_credit);
end if;
end;
/
-- 创建存储过程
create or replace procedure student_credit(name in varchar2, total out number)
as
begin
select sum(credit) into total from XS where sname = name;
end;
/
-- 调用结果
declare
stotal integer;
begin
student_credit('stu02', stotal);
dbms_output.put_line('输出结果:'||stotal);
end;
/
4、创建存储过程用来计算这个参数的平方或者平方根
创建一个存储过程,在其中定义一个IN OUT参数,该存储过程用来计算这个参数的平方或者平方根。
-- 创建存储过程
create or replace procedure pro_squre(num in out number, flag in boolean)
as
i int := 2;
begin
if flag then
num := power(num, i);
else
num := sqrt(num);
end if;
end;
/
-- 调用结果
declare
v_number number;
v_temp number;
v_flag boolean;
begin
v_temp := &number;
v_number := v_temp;
v_flag := &flag;
pro_squre(v_number, v_flag);
if v_flag then
dbms_output.put_line(v_temp ||'的平方是:' ||v_number);
else
dbms_output.put_line(v_temp ||'的平方根是:' ||v_number);
end if;
end;
/
函数:
1、创建一个通过雇员编号返回雇员名称的函数。
假设某公司需要创建一雇员表(employees),该表的已知需求如下:
雇员编号(EMPNO,4位数字),雇员名字(ENAME,最多10个字符),工种(JOB,最多10个字符),经理的编号(MGR,4位数字),聘用日期(HIREDATE),工资(SAL,保留2位小数),年终奖金比例(COMM,保留2位小数),所属部门编号( DEPTNO,3位数字)
create table employees(
empno number(4)not null,
ename varchar2(10),
job varchar2(9),
mgr number(4),
hiredate date,
sal number(7,2),
comm number(7,2),
deptno number(3));
修改表employees,删除字段年终奖金比例,添加字段奖金bonus,保留两位小数。
alter table employees drop column comm;
alter table employees add(bonus number(5, 2));
注意:本题需要创建用户并连接用户,在用户中进行表操作,因为超级用户 SYS 用户表中的列无法删除
执行结果:
--插入数据
insert into employees values(101, '雇员1', '工程师', '001', sysdate, 2500, 001, 500);
insert into employees values(102, '雇员2', '工程师', '001', sysdate, 2500, 001, 500);
insert into employees values(103, '雇员3', '工程师', '001', sysdate, 2500, 001, 500);
创建一个通过雇员编号返回雇员名称的函数GET_EMP_NAME。
要求进行异常处理,其中NO_DATA_FOUND没有符合条件记录,TO_MANY_ROWS返回多条符合条件记录。
-- 创建函数
create or replace function get_emp_name(p_empno number default 7788)
return varchar2
as
v_ename varchar2(10);
begin
select ename into v_ename from employees where empno=p_empno;
return v_ename;
exception
when no_data_found then
dbms_output.put_line('没有该聘员编号!!');
return null;
when too_many_rows then
dbms_output.put_line('重复该聘员编号!!');
return null;
when others then
dbms_output.put_line('发生其他错误!');
return (null);
end;
/
-- 调用函数
declare
v_ename employees.ename %TYPE;
begin
v_ename:=get_emp_name(101);
dbms_output.put_line('雇员的名字是:'||v_ename);
end;
/
执行结果:
2、创建一数据库函数,返回指定日期的收费总和
已知电信收费表call_fee,该表的已知需求如下:
包括交费日期(in_date,日期型)、话费(charge,数字型)和滞纳金(late_fee,数字型)等字段。不是每笔交费记录都包含有滞纳金,注意空值的处理。
-- 创建表
create table call_fee(
in_date DATE,
charge number(4),
late_fee number(4)
);
-- 插入数据
insert into call_fee values(to_date('2020-10-10','yyyy-mm-dd'), 100, 200);
insert into call_fee values(to_date('2020-10-15','yyyy-mm-dd'), 200, 400);
-- 创建函数
create or replace function countfee(v_date date)
return number
as
v_fee number;
begin
select sum(charge)+sum(nvl(late_fee,0)) into v_fee from call_fee where in_date = v_date;
return v_fee;
end;
/
--执行函数
declare
v_fee number;
v_date date := to_date('2020-10-10','yyyy-mm-dd');
begin
v_fee := countfee(v_date);
dbms_output.put_line(v_date||'共花费:'||v_fee);
end;
/
以上是关于Oracle——存储过程和函数练习题的主要内容,如果未能解决你的问题,请参考以下文章