热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

《OraclePL/SQL实例精讲》学习笔记21——包(第三部分)

本章内容:1.创建包(创建包规范、包体、调用已存储的包、创建私有对象)2.游标变量3.用其他程序扩展包4.包的实例化和初始化5.

本章内容:

1. 创建包(创建包规范、包体、调用已存储的包、创建私有对象)

2. 游标变量

3. 用其他程序扩展包

4. 包的实例化和初始化

5. SERIALLY_RESABLE包

代码入下:

1. 创建包规范

SQL> -- For Example ch21_15.sql
SQL> CREATE OR REPLACE PACKAGE MANAGE_GRADES AS2 -- Cursor to loop through all grade types for a given section.3 CURSOR c_grade_type4 (pc_section_id section.section_id%TYPE,5 PC_student_ID student.student_id%TYPE)6 IS7 SELECT GRADE_TYPE_CODE,8 NUMBER_PER_SECTION,9 PERCENT_OF_FINAL_GRADE,10 DROP_LOWEST11 FROM grade_Type_weight12 WHERE section_id = pc_section_id13 AND section_id IN (SELECT section_id14 FROM grade15 WHERE student_id = pc_student_id);16 -- Cursor to loop through all grades for a given student17 -- in a given section.18 CURSOR c_grades19 (p_grade_type_code20 grade_Type_weight.grade_type_code%TYPE,21 pc_student_id student.student_id%TYPE,22 pc_section_id section.section_id%TYPE) IS23 SELECT grade_type_code,grade_code_occurrence,24 numeric_grade25 FROM grade26 WHERE student_id = pc_student_id27 AND section_id = pc_section_id28 AND grade_type_code = p_grade_type_code;29 -- Function to calcuation a students final grade30 -- in one section31 Procedure final_grade32 (P_student_id IN student.student_id%type,33 P_section_id IN section.section_id%TYPE,34 P_Final_grade OUT enrollment.final_grade%TYPE,35 P_Exit_Code OUT CHAR);36 END MANAGE_GRADES;37 /Package created.

2. 创建包体

SQL> -- For Example ch21_17.sql
SQL> CREATE OR REPLACE PACKAGE BODY MANAGE_GRADES AS2 Procedure final_grade3 (P_student_id IN student.student_id%type,4 P_section_id IN section.section_id%TYPE,5 P_Final_grade OUT enrollment.final_grade%TYPE,6 P_Exit_Code OUT CHAR)7 IS8 v_student_id student.student_id%TYPE;9 v_section_id section.section_id%TYPE;10 v_grade_type_code grade_type_weight.grade_type_code%TYPE;11 v_grade_percent NUMBER;12 v_final_grade NUMBER;13 v_grade_count NUMBER;14 v_lowest_grade NUMBER;15 v_exit_code CHAR(1) := 'S';16 v_no_rows1 CHAR(1) := 'N';17 v_no_rows2 CHAR(1) := 'N';18 e_no_grade EXCEPTION;19 BEGIN20 v_section_id := p_section_id;21 v_student_id := p_student_id;22 -- Start loop of grade types for the section.23 FOR r_grade in c_grade_type(v_section_id, v_student_id)24 LOOP25 -- Since cursor is open it has a result26 -- set, change indicator.27 v_no_rows1 := 'Y';28 -- To hold the number of grades per section,29 -- reset to 0 before detailed cursor loops30 v_grade_count := 0;31 v_grade_type_code := r_grade.GRADE_TYPE_CODE;32 -- Variable to hold the lowest grade.33 -- 500 will not be the lowest grade.34 v_lowest_grade := 500;35 -- Determine what to multiply a grade by to36 -- compute final grade, must take into consideration37 -- if the drop lowest grade indicator is Y38 SELECT (r_grade.percent_of_final_grade /39 DECODE(r_grade.drop_lowest, 'Y',40 (r_grade.number_per_section - 1),41 r_grade.number_per_section42 ))* 0.0143 INTO v_grade_percent44 FROM dual;45 -- Open cursor of detailed grade for a student in a46 -- given section.47 FOR r_detail in c_grades(v_grade_type_code,48 v_student_id, v_section_id) LOOP49 -- Since cursor is open it has a result50 -- set, change indicator.51 v_no_rows2 := 'Y';52 v_grade_count := v_grade_count + 1;53 -- Handle the situation where there are more54 -- entries for grades of a given grade type55 -- than there should be for that section.56 If v_grade_count > r_grade.number_per_section THEN57 v_exit_code := 'T';58 raise e_no_grade;59 END IF;60 -- If drop lowest flag is Y determine which is lowest61 -- grade to drop62 IF r_grade.drop_lowest = 'Y' THEN63 IF nvl(v_lowest_grade, 0) >=64 r_detail.numeric_grade65 THEN66 v_lowest_grade := r_detail.numeric_grade;67 END IF;68 END IF;69 -- Increment the final grade with percentage of current70 -- grade in the detail loop.71 v_final_grade := nvl(v_final_grade, 0) +72 (r_detail.numeric_grade * v_grade_percent);73 END LOOP;74 -- Once detailed loop is finished, if the number of grades75 -- for a given student for a given grade type and section76 -- is less than the required amount, raise an exception.77 IF v_grade_count 100 P_exit_code := v_exit_code;
101 WHEN OTHERS THEN
102 P_final_grade := null;
103 P_exit_code := 'E';
104 END final_grade;
105 END MANAGE_GRADES;
106 /

3. 查看包

SQL> desc manage_grades
PROCEDURE FINAL_GRADEArgument Name Type In/Out Default?------------------------------ ----------------------- ------ --------P_STUDENT_ID NUMBER(8) INP_SECTION_ID NUMBER(8) INP_FINAL_GRADE NUMBER(3) OUTP_EXIT_CODE CHAR OUT

4. 测试

SQL> set serverout on
SQL> DECLARE2 v_student_id student.student_id%TYPE := &sv_student_id;3 v_section_id section.section_id%TYPE := &sv_section_id;4 v_final_grade enrollment.final_grade%TYPE;5 v_exit_code CHAR;6 BEGIN7 manage_grades.final_grade(v_student_id, v_section_id,8 v_final_grade, v_exit_code);9 DBMS_OUTPUT.PUT_LINE('The Final Grade is '||v_final_grade);10 DBMS_OUTPUT.PUT_LINE('The Exit Code is '||v_exit_code);11 END;12 /
Enter value for sv_student_id: 102
old 2: v_student_id student.student_id%TYPE := &sv_student_id;
new 2: v_student_id student.student_id%TYPE := 102;
Enter value for sv_section_id: 89
old 3: v_section_id section.section_id%TYPE := &sv_section_id;
new 3: v_section_id section.section_id%TYPE := 89;
The Final Grade is 92
The Exit Code is S

5. 更新包头


SQL> -- For Example ch21_19.sql
SQL> CREATE OR REPLACE PACKAGE MANAGE_GRADES AS2 -- Cursor to loop through all grade types for a given section.3 CURSOR c_grade_type4 (pc_section_id section.section_id%TYPE,5 PC_student_ID student.student_id%TYPE)6 IS7 SELECT GRADE_TYPE_CODE,8 NUMBER_PER_SECTION,9 PERCENT_OF_FINAL_GRADE,10 DROP_LOWEST11 FROM grade_Type_weight12 WHERE section_id = pc_section_id13 AND section_id IN (SELECT section_id14 FROM grade15 WHERE student_id = pc_student_id);16 -- Cursor to loop through all grades for a given student17 -- in a given section.18 CURSOR c_grades19 (p_grade_type_code20 grade_Type_weight.grade_type_code%TYPE,21 pc_student_id student.student_id%TYPE,22 pc_section_id section.section_id%TYPE) IS23 SELECT grade_type_code,grade_code_occurrence,24 numeric_grade25 FROM grade26 WHERE student_id = pc_student_id27 AND section_id = pc_section_id28 AND grade_type_code = p_grade_type_code;29 -- Function to calcuation a students final grade30 -- in one section31 Procedure final_grade32 (P_student_id IN student.student_id%type,33 P_section_id IN section.section_id%TYPE,34 P_Final_grade OUT enrollment.final_grade%TYPE,35 P_Exit_Code OUT CHAR);36 -- ---------------------------------------------------------37 -- Function to calculate the median grade38 FUNCTION median_grade39 (p_course_number section.course_no%TYPE,40 p_section_number section.section_no%TYPE,41 p_grade_type grade.grade_type_code%TYPE)42 RETURN grade.numeric_grade%TYPE;43 CURSOR c_work_grade44 (p_course_no section.course_no%TYPE,45 p_section_no section.section_no%TYPE,46 p_grade_type_code grade.grade_type_code%TYPE47 )IS48 SELECT distinct numeric_grade49 FROM grade50 WHERE section_id = (SELECT section_id51 FROM section52 WHERE course_no= p_course_no53 AND section_no = p_section_no)54 AND grade_type_code = p_grade_type_code55 ORDER BY numeric_grade;56 TYPE t_grade_type IS TABLE OF c_work_grade%ROWTYPE57 INDEX BY BINARY_INTEGER;58 t_grade t_grade_type;59 END MANAGE_GRADES;60 /Package created.

6. 更新包体

-- For Example ch21_20.sql
CREATE OR REPLACE PACKAGE MANAGE_GRADES AS
CREATE OR REPLACE PACKAGE BODY MANAGE_GRADES ASProcedure final_grade(P_student_id IN student.student_id%type,P_section_id IN section.section_id%TYPE,P_Final_grade OUT enrollment.final_grade%TYPE,P_Exit_Code OUT CHAR)
ISv_student_id student.student_id%TYPE;v_section_id section.section_id%TYPE;v_grade_type_code grade_type_weight.grade_type_code%TYPE;v_grade_percent NUMBER;v_final_grade NUMBER;v_grade_count NUMBER;v_lowest_grade NUMBER;v_exit_code CHAR(1) := 'S';-- Next two variables are used to calculate whether a cursor-- has no result set.v_no_rows1 CHAR(1) := 'N';v_no_rows2 CHAR(1) := 'N';e_no_grade EXCEPTION;
BEGINv_section_id := p_section_id;v_student_id := p_student_id;-- Start loop of grade types for the section.FOR r_grade in c_grade_type(v_section_id, v_student_id)LOOP-- Since cursor is open it has a result-- set, change indicator.v_no_rows1 := 'Y';-- To hold the number of grades per section,-- reset to 0 before detailed cursor loopsv_grade_count := 0;v_grade_type_code := r_grade.GRADE_TYPE_CODE;-- Variable to hold the lowest grade.-- 500 will not be the lowest grade.v_lowest_grade := 500;-- Determine what to multiply a grade by to-- compute final grade, must take into consideration-- if the drop lowest grade indicator is YSELECT (r_grade.percent_of_final_grade /DECODE(r_grade.drop_lowest, 'Y',(r_grade.number_per_section - 1),r_grade.number_per_section))* 0.01INTO v_grade_percentFROM dual;-- Open cursor of detailed grade for a student in a-- given section.FOR r_detail in c_grades(v_grade_type_code,v_student_id, v_section_id) LOOP-- Since cursor is open it has a result-- set, change indicator.v_no_rows2 := 'Y';v_grade_count := v_grade_count + 1;-- Handle the situation where there are more-- entries for grades of a given grade type-- than there should be for that section.If v_grade_count > r_grade.number_per_section THENv_exit_code := 'T';raise e_no_grade;END IF;-- If drop lowest flag is Y determine which is lowest-- grade to dropIF r_grade.drop_lowest = 'Y' THENIF nvl(v_lowest_grade, 0) >=r_detail.numeric_gradeTHENv_lowest_grade := r_detail.numeric_grade;END IF;END IF;-- Increment the final grade with percentage of current-- grade in the detail loop.v_final_grade := nvl(v_final_grade, 0) +(r_detail.numeric_grade * v_grade_percent);END LOOP;-- Once detailed loop is finished, if the number of grades-- for a given student for a given grade type and section-- is less than the required amount, raise an exception.IF v_grade_count RETURN grade.numeric_grade%TYPEISBEGINFOR r_work_grade IN c_work_grade(p_course_number, p_section_number, p_grade_type) LOOPt_grade(NVL(t_grade.COUNT,0) + 1).numeric_grade := r_work_grade.numeric_grade;END LOOP;IF t_grade.COUNT = 0THENRETURN NULL;ELSEIF MOD(t_grade.COUNT, 2) = 0THEN-- There is an even number of workgrades. Find the middle-- two and average them.RETURN (t_grade(t_grade.COUNT / 2).numeric_grade +t_grade((t_grade.COUNT / 2) + 1).numeric_grade) / 2;ELSE-- There is an odd number of grades. Return the one in the middle.RETURN t_grade(TRUNC(t_grade.COUNT / 2, 0) + 1).numeric_grade;END IF;END IF;EXCEPTIONWHEN OTHERSTHENRETURN NULL;END median_grade;
END MANAGE_GRADES;

7. 重新测试

 


推荐阅读
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
author-avatar
暗罗华怡
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有