第24章包在PL/SQL中,包是一个模式对象,通过一定的逻辑组合,可以将相关的类型、常量、变量、存储过程、函数和异常组合在一起。一个包由两部分组成,包说明和包体。这两个部分是相互独立的。每一个部分在数据字典中都可以单独存储。PL/SQL中的包具有模块化、可以隐藏实施细节、方便应用程序设计、重载子程序以及良好的性能等特点。这一章就来介绍PL/SQL中的包。包的创建;包中公有元素的调用;包中子程序的重载;包的删除方法;Oracle数据库中常用内置系统包。24.1创建包PL/SQL中的包由包说明和包体两个独立的部分组成。包说明部分是应用程序的接口,主要包含包的内容信息,在包说明中声明了变量、常量、游标、自定义数据类型、存储过程或者函数;包体部分主要用来实现包说明中的内容,而且在包体部分还可以定义自己私有的游标、存储过程或者函数。包体不是必需的。本节就来介绍包说明和包体的创建。24.1.1创建包说明在PL/SQL中,如果要创建一个包,首先需要创建包说明,然后再创建包体,这一小节就来介绍包说明的创建。创建包说明可以使用CREATE[ORREPLACE]PACKAGE语句来完成。其创建包说明的语法规则如下:24.1.1创建包说明CREATE[ORREPLACE]PACKAGEpackage_name{IS|AS}[variable_declaration...]--声明变量[cursor_declaration...]--声明游标[exception_declaration...]--声明异常[object_declaration...]--声明对象[function_declaration...]--声明函数[procedure_declaration...]--声明过程END[package_name];24.1.1创建包说明CREATEORREPLACEPACKAGEstudent_packageASg_curIDVARCHAR2(15);--声明变量g_c_rateNBUMBER:=1.5;--声明常量TYPEstudentResult_arrayt_result.result%TYPEINDEXBYBINARY_INTEGER;--声明可变数组PROCEDUREins_result--声明过程(p_stuIDINt_t_result.stuID%TYPE,p_curIDINt_result.curID%TYPE);PROCEDUREdelete_result--声明过程(p_stuIDINt_t_result.stuID%TYPE,p_curIDINt_result.curID%TYPE);CREATEORREPLACEFUNCTIONget_student--声明函数(p_stuIDt_student.stuID%TYPE)RETURNt_student%ROWTYPE;e_illegalValueEXCEPTION;--声明异常e_illegalResult--声明异常ENDstudent_package;24.1.2创建包体包体部分主要用来实现包说明中的内容,在包体中包含了包说明中声明的每一个游标、函数或者是存储过程的实现。在包体中也可以有自己的变量、常量、游标、自定义数据类型、存储过程或者函数,但是这些元素都是私有的,不能由其他的PL/SQL语句块或者是应用程序进行引用。可以使用CREATEPACKAGEBODY创建一个包体。其创建包体的语法规则如下:24.1.2创建包体CREATE[ORREPLACE]PACKAGEBODYpackage_name{IS|AS}--公有变量、常量、游标、自定义数据类型、存储过程或者函数的实现--定义私有的变量、常量、游标、自定义数据类型、存储过程或者函数ENDpackage_name;24.2调用包中的公有元素在前面的一节中已经介绍过,在包说明中声明的变量、常量、游标、自定义数据类型、存储过程或者函数都是公有的。既然是这些元素是公有的的,那么就可以被其他的应用程序所调用。例如,可以在PL/SQL语句块中调用student_package包的ins_result存储过程。其调用方法如下:BEGINstudent_package.ins_result('s102203','t105');END;24.3在包中使用重载在PL/SQL中,存储过程和函数可以在包中重载。包的重载特性允许在一个包内定义多个名称相同但是参数不同的子程序(包括存储过程和函数)。也就是说,不同的子程序可以有相同的名字,只要保证其形参的参数数量、参数顺序或者是数据类型不同即可(类似与Java语言的方法重载)。当调用包中的某一个子程序时,PL/SQL会比较形参列表和实参列表,并根据形参列表和实参列表的比较结果选择合适的子程序。24.3在包中使用重载CREATEORREPLACEPACKAGElearntime_package--包说明ASPROCEDUREget_courseLearntime(p_curIDINt_curriculum.curID%TYPE);PROCEDUREget_courseLearntime(p_curNameINt_curriculum.curName%TYPE,p_creditINt_curriculum.credit%TYPE);ENDlearntime_package;24.3在包中使用重载但是,在包中对子程序在使用重载时,还是有一些限制的。在下面的这些情况下,使用重载将是不合法的。如果两个子程序参数类型相同,只是参数的名称和指定的参数方式不同,则不能进行重载。例如,下面的这两个存储过程的重载就是非法的。PROCEDUREget_courseLearntime(p_curNameVARCHAR2)PROCEDUREget_courseLearntime(p_curIDVARCHAR2)24.3在包中使用重载两个子程序虽然参数类型不相同,但是其参数类型都是同一个类型的(例如,都是字符类型、数字类型等),也不能进行重载。例如,下面的这两个存储过程的重载就是非法的。PROCEDUREget_courseLearntime(p_curNameCHAR)PROCEDUREget_courseLearntime(p_curIDVARCHAR2)这里CHAR和VARCHAR2都属于字符类型。24.3在包中使用重载如果两个函数只是返回值类型不同,则不能进行重载例如,下面的这两个函数的重载就是非法的。FUNCTIONget_salaryRETURNNUMBER;FUNCTIONget_salaryRETURNVARCHAR2;24.4删除包使用DROP命令也可以删除包。如果只是想删除包体,而不想删除包说明,可以使用DROPPACKAGEBODY命令。其删除包体的语法规则如下:DROPPACKAGEBODYpackagebody_name;其中,packagebody_name为要删除的包体的名字。24.5系统包在Oracle数据库及其Oracle工具中包括许多内置的系统包,例如,前面的章节中经常出现的DBMS_OUTPUT就是一个用于提供输入输出信息的包。通过这些内置的系统包可以为PL/SQL的应用程序实现许多其他的功能。例如,文件读写、会话通信等功能。这一章就来简要介绍一些其中比较重要的包。24.5.1生成并发送报警信息的包DBMS_ALERTDBMS_ALERT包是用于生成并发送报警信息。通过使用DBMS_ALERT包可以在特定的数据库值发生变化时,将报警信息传递给应用程序。注意:只有SYS和SYSTEM权限的用户以及被授予EXECUTE权限的其他用户才可以使用DBMS_ALERT包。对于没有SYS和SYSTEM权限的用户要想使用可以使用DBMS_ALERT包,需要被授予EXECUTE权限。可以使用GRANT命令为其他用户授予EXECUTE权限。例如,为用户’admin’1授予EXECUTE权限,就可以使用下面的语句来完成。GRANTEXECUTEONDBMS_ALERTTO‘admin’1;24.5.1生成并发送报警信息的包DBMS_ALERTDBMS_ALERT包中所包含的主要过程1.SIGNAL过程2.WAITANY和WAITONE过程3.REGISTER过程4.REMOVE和REMOVEALL过程5.SET_DEFAULTS过程24.5.2输入和输出信息的包DBMS_OUTPUT包DBMS_OUTPUT用来输入和输出信息,方便程序的测试与调试。其中,过程PUT和PUT_LINES可以将信息发送到SGA的一个缓存中,过程GET_LINE和GET_LINES可以显示缓存中的信息。DBMS_OUTPUT包中所包含的主要过程1.DISABLE和ENABLE过程2.PUT和PUT_LINE过程3.GET_LINE和GET_LINES过程24.5.3进行管道通信的包DBMS_PIPEDBMS_PIPE包用于在同一例程的不同会话之间进行管道通信,所谓管道可以认为是一块内存区域。不同的会话之间可以通过管道发送消息。两个会话可以不在同一台机器上,只要它们可以向服务器发送PL/SQL命令,那么这两个会话之间就可以进行通信。注意:管道是异步的,一旦向管道发送了一条消息,就不能取消它。24.5.3进行管道通信的包DBMS_PIPE如果用户要执行DBMS_PIPE包中的过程和函数,则必须要为用户授予EXECUTE权限。可以使用GRANT命令为用户授予EXECUTE权限。例如,为用户’admin’1授予EXECUTE权限,就可以使用下面的语句来完成。GRANTEXECUTEONDBMS_PIPETO‘admin’1;24.5.3进行管道通信的包DBMS_PIPEDBMS_PIPE包中的主要过程和函数1.CREATE_PIPE函数2.PACK_MESSAGE过程3.SEND_MESSAGE函数4.RECEIVE_MESSAGEG函数5.UNPACK_MESSAGE过程6.NEXT_ITEM_TYP函数7.REMOVE_PIPE函数8.PURGE过程24.5.4安排和管理PL/SQL语句块的包DBMS_JOBDBMS_JOB包用于安排和管理PL/SQL语句块,使Oracle数据库可以在指定的时间执行特定的任务.。这些PL/SQL语句块会交由Oracle数据库的后台进程负责处理。DBMS_JOB包中所包含的主要过程和函数。1.SUBMIT过程2.RUN过程3.CHANGE过程4.REMOVE过程24.5.5处理LOB数据类型数据的包DBMS_LOBDBMS_LOB包主要是用来处理LOB数据类型(例如,BFILE、BLOB、CLOB和NCLOB)的数据。可以对这些数据进行比较、复制、获取LOB数据某一个特定部分内容等操作。DBMS_LOB包中所包含的主要过程和函数。1.APPEND过程2.COMPARE函数3.GETLENGT函数4.COPY过程