[*用Oracle来创建学生信息管理系统(续2)*]
来源:互联网 发布:淘宝直播秒杀是真的吗 编辑:程序博客网 时间:2024/06/04 19:46
–应用报表
–1、输入班级号,打印输出当前班级信息及当前班级中的学生信息
–创建报表打印的PL/SQL块如下:
–分析:
–一、根据要求,需要动态输入班级号,可使用带参数的游标;
–二、班级号是主键,可以用select into 语句直接获取班级信息;
–三、学生有多个,需要单独处理每个学生,可用游标;
–四、会存在班号输入错误,引入异常处理
–Oracle数据库中,所有的查询语句select的使用,
–系统都会产生相应的游标
–所有的游标分两类:隐式游标,显式游标需要通过游标类型变量的定义
declare/*声明带参数的游标*/cursor student_cursor(p_clno class.clno%type)isselect * from student where clno=p_clno;/*学生记录类型*/student_record student%rowtype;/*班级记录类型*/class_record class%rowtype;/*班级编号*/v_clno class.clno%type;/*班级人数*/v_count number(2);v_sex varchar2(2);--报表块主体部分beginv_clno:=upper('&p_clno');/*取得班级信息*/select * into class_record from class where clno=v_clno;/*取得班级人数*/select count(*) into v_count from student where clno=v_clno group by clno;dbms_output.put_line(class_record.dept||'系'||class_record.grade||class_record.branch||'总共有:'||v_count||'人');dbms_output.put_line('_____________________________');/*取得当前班级的学生信息*/open student_cursor(v_clno);loopfetch student_cursor into student_record;exit when student_cursor%notfound;if student_record.sex='1'then v_sex:='男'; else v_sex:='女';end if;dbms_output.put_line('学号:'||student_record.sno||',姓名:' ||student_record.name||',年龄:'||student_record.age||',性别:' ||v_sex||',入学日期:' ||to_char(student_record.entrance,'yyyy-mm-dd'));end loop; close student_cursor;exception when no_data_found then dbms_output.put_line('指定的班级号不存在!');end;
2、根据业务要求,需定义一个报表打印,要求输出所有课程的信息
(课程编号,课程名称,课程学分);
并打印输出针对当前课程按照授课教师分组,所教学生的人数
以及学生的平均得分;
(教师号,教师姓名,学生人数,学生平均得分)
分析:
- 需要输出所有课程的信息,涉及多条数据处理,需要引入游标
- 再按照课程分组,输出每个教师所教学生的人数及平均得分时,
需首先确定课程,分析一、中的数据** - 创建视图:教师号,教师姓名,学生人数,学生平均得分
解决方案:
1、创建视图,按课程和教师分组,统计每个教师所教学生人数、
其所负责课程名称及所教学生在此课程所得成绩的平均值。
create or replace view vw_course_teacherasselect c.cno,t.tno,t.name tname,count(*) stu_count,trunc(avg(st.grade),2) score_avgfrom teacher t join st st on t.tno=st.tnojoin course c on t.cno=c.cnogroup by(c.cno,t.tno,t.name);
2、创建报表打印的PL/SQL如下:
declare /*课程游标*/ cursor course_cursor is select cno,name,score from course; /*基于vw_course_teacher声明带参数的游标*/ cursor vw_c_t_cursor(p_cno course.cno%type) is select * from vw_course_teacher where cno=p_cno; /*课程记录类型*/ course_record course%rowtype; /*vw_course_teacher记录类型*/ vw_c_t_record vw_course_teacher%rowtype; /*统计选择当前课程的人数*/ v_stu_count int; /*统计选择当前课程的学生的平均分*/ v_score_avg number(4,2);begin open course_cursor; loop /*取得课程记录*/ fetch course_cursor into course_record; exit when course_cursor%notfound; /*打印课程信息*/ dbms_output.put_line('课程号:'||course_record.cno); dbms_output.put_line('课程名:'||course_record.name); dbms_output.put_line('总学分:'||course_record.score); dbms_output.put_line(''); /*根据当前课程编号,打开基于vw_course_teacher的游标*/ open vw_c_t_cursor(p_cno=>course_record.cno); v_stu_count:=0; v_score_avg:=0; /*打印报表表头*/ dbms_output.put_line(LPAD('教师号',10,' ') ||LPAD('教师姓名',12,' ') ||LPAD('学生人数',12,' ')||LPAD('平均分',10,' ')); loop fetch vw_c_t_cursor into vw_c_t_record; exit when vw_c_t_cursor%notfound; v_stu_count:=v_stu_count+vw_c_t_record.stu_count; v_score_avg:=v_score_avg+ vw_c_t_record.score_avg*vw_c_t_record.stu_count; dbms_output.put_line(LPAD(vw_c_t_record.tno,10,' ') ||LPAD(vw_c_t_record.tname,12,' ') ||LPAD(vw_c_t_record.stu_count,12,' ') ||LPAD(vw_c_t_record.score_avg,10,' ')); end loop; dbms_output.put_line(LPAD(RPAD(' ',22,'-'),44,' ')); dbms_output.put_line('总计'||LPAD(v_stu_count,30,' ') ||LPAD(v_score_avg/v_stu_count,10,' ')); close vw_c_t_cursor; dbms_output.put_line(''); dbms_output.put_line(LPAD('- ',44,'- ')); end loop; close course_cursor;end;
异常处理
1、异常简介:在编写PL/SQL块时,应该捕捉并处理各种可能出现的异常。
如果不捕捉和处理异常,Oracle会将错误传递到调用环境,
整个程序运行自动终止,并不提示任何错误信息;
如果捕捉并处理异常,那么Oracle会在PL/SQL块内解决运行错误。
在PL/SQL,一般将异常处理部分放在PL/SQL程序体的后半部,其语法结构为:
exception when exception1 then <对于exception1的处理语句> when exception2 then <对于exception2的处理语句> when others then <对于其他异常的处理语句>end;
Others不是必需的,但Others必须放在最后。
对两数相除可能出现的错误进行处理
declare v_n1 int:=&n1; v_n2 int:=&n2; v_div int;beginv_div:=v_n1/v_n2;dbms_output.put_line(v_n1||'/'||v_n2||'='||v_div);exception when zero_divide then dbms_output.put_line('除数不能为零!'); when others then dbms_output.put_line('出现未知错误!');end;
2、异常处理
Oracle中的异常包括预定义异常、非预定义异常和自定义异常三种类型
预定义异常
declare emp_record emp%rowtype;begin select * into emp_record from emp where sal=&p_sal; dbms_output.put_line('雇员姓名:'||emp_record.ename||',工资:'||emp_record.sal); exception when no_data_found then dbms_output.put_line('不存在该工资的雇员!'); when too_many_rows then dbms_output.put_line('该工资的雇员有多个!');end;
由于经常对学生信息表进行操作,为方便管理和提高代码执行速度,
需要将学生信息表的增、删、改、查封装到包内使用子过程实现,
以方便应用程序JAVA调用。
分析
- 使用包可以使程序设计模块化,而且可以提高程序的执行效率。
- 对于学生信息增加操作,可使用记录类型作为输入参数的过程实现。
- 对于查询操作,需要根据学生号查询学生信息,并能返回所有学生信息
- 对于修改操作,需要能够根据指定的条件,动态构造修改语句,在Oracle中
可以使用EXECUTE IMMEDIATE过程动态地执行本地SQL。
参考的解决方案
1、定义包规范如下:
create or replace package student_packis /*统计学生人数*/ v_count int; /*增加学生信息*/ procedure add_student(student_record student%rowtype); /*根据指定条件修改学生信息*/ procedure update_student(p_modifiers varchar2,p_condition varchar2); /*根据学生号删除学生信息*/ procedure del_student(p_sno student.sno%type); /*根据学生号查询学生信息*/ function get_student(p_sno student.sno%type) return student%rowtype; /*定义基于记录类型的嵌套表*/ type student_table_type is table of student%rowtype; /*获得所有学生的信息*/ function get_student return student_table_type;end student_pack;
2、对于student_pack包的包体代码如下:
create or replace package body student_packis/*check_student是包体的私有子程序*/ function check_student(p_sno student.sno%type) return boolean is v_count int; begin select count(*) into v_count from student where sno=p_sno; if v_count>0 then return true; else return false; end if; end check_student; /*实现add_student过程*/ procedure add_student(student_record student%rowtype) is begin if check_student(student_record.sno)=false then insert into student values(student_record.sno,student_record.name, student_record.age,student_record.sex, student_record.entrance,student_record.address, student_record.clno,student_record.family); dbms_output.put_line('添加成功!'); else dbms_output.put_line('添加失败:学生编号冲突!'); end if; exception when others then dbms_output.put_line('添加错误:'||SQLCODE||'----'||SQLERRM); end add_student; /*实现update_student过程*/ procedure update_student(p_modifiers varchar2,p_condition varchar2) is begin execute immediate 'update student'||'set' ||p_modifiers||'where'||p_condition; exception when others then dbms_output.put_line('修改出错:'||SQLCODE||'----'||SQLERRM); end; /*实现del_student过程*/ procedure del_student(p_sno student.sno%type) is begin if check_student(p_sno)=true then delete from student where sno=p_sno; dbms_output.put_line('删除成功!'); else dbms_output.put_line('删除失败:指定的学生不存在!'); end if; exception when others then dbms_output.put_line('删除出错:'||SQLCODE||'----'||SQLERRM); end del_student; /*实现get_student函数*/ function get_student(p_sno student.sno%type) return student%rowtype is student_record student%rowtype; no_result exception; begin if check_student(p_sno)=true then select * into student_record from student where sno=p_sno; return student_record; else raise no_result; end if; exception when no_result then raise_application_error(-20099,'查询的学生不存在'); when others then /*输出错误编码和消息*/ --dbms_output.put_line(SQLCODE||'----'||SQLERRM); raise_application_error(-20100,'查询出错'); end get_student; /*实现get_student函数*/ function get_student return student_table_type is student_table student_table_type; begin select * bulk collect into student_table from student; return student_table; end get_student; /*获取学生总人数*/begin select count(*) into v_count from student;end student_pack;--用于测试student_pack功能的PL/SQL语句如下:/*添加过程测试*/declare student_record student%rowtype;beginstudent_record.sno:=&add_sno;student_record.name:=&add_name;student_record.age:=&add_age;student_record.sex:=&add_sex;student_record.entrance:=&add_entr;student_record.address:=&add_addr;student_record.clno:=&add_clno;student_record.family:=&add_fami;student_pack.add_student(student_record);end;/*删除过程测试*/declarestudent_record student%rowtype;beginstudent_record.sno:=&del_sno;student_pack.del_student(student_record.sno);end;
–包的调用
call student_pack.get_student('1462105');
–过程调用
call zxx_package2.sal_pro1('CLERK',0.01);
–函数的调用
var vsal number;call zxx_package2.avg_sal(10) into:vsalselect zxx_package2.avg_sal(10) from dual;
call student_pack.check_student('1462119');declarebegin student_pack.get_student('1462119');end;
var v_ck boolean;call student_pack.check_student('1462140819') into:v_ck;select student_pack.check_student('1462140819') from dual;
- [*用Oracle来创建学生信息管理系统(续2)*]
- [*用Oracle来创建学生信息管理系统*]
- [*用Oracle来创建学生信息管理系统(续1)*]
- 学生信息管理系统之优化问题续
- 学生信息管理系统之恍然大悟(2)
- 学生信息管理系统错误集(2)
- 练手小程序2 学生信息管理系统
- 学生信息管理系统之错误百出2
- 学生信息管理系统
- 学生学籍信息管理系统
- 学生信息管理系统
- 学生信息管理系统
- 学生成绩信息管理系统
- 学生信息管理系统
- 【学生信息管理系统 总结】
- 学生信息管理系统--毕业论文
- 学生信息管理系统
- 学生信息管理系统
- Centos7下通过zabbix监控nginx status
- web/html5调用摄像头实现二维码扫描
- yii2 phpexecl导入
- PHP的Yii框架中移除组件所绑定的行为的方法
- Github Page---- 搭建个人博客网站
- [*用Oracle来创建学生信息管理系统(续2)*]
- CVPR2016代码合集
- hadoop安装和维护05--配置yum源
- 169. Majority Element
- Newtonsoft.Json高级用法
- string中c_str()、data()、copy(p,n)函数的用法
- kafka 配置大全(中文,英文)
- echarts折线图不堆叠设置
- perl和python各自擅长什么领域?