PL/SQL之包
1、包的定义
一个包由两个独立的部分组成--包头和包体。给部分被单独地存放在数据字典中。
1.1定义包头 语法: CREATE [OR REPLACE] PACKAGE [schema.] package {IS|AS} pl/sql_package; package是包的名称 pl/sql_package可以是存储过程、函数、变量、类型、异常以及游标的定义。 存储过程或函数必须在包头中预定义。也就是说,在包头中定义存储过程名或函数名以及它们的参数,存储过程或函数的执行代码将在包体中定义。 CREATE OR REPLACE AuthsPack AS --获得auths表中作家的工资 PROCEDURE QuerySalary(p_Code auths.author_code%TYPE,p_Salary auths.salary%TYPE); --向auths表插入记录 PROCEDURE InsertAuthor(p_Code auths.author_code%TYPE,p_Name auths.name%TYPE); END AuthsPack; 1.2定义包体 包体是一个数据字典对象。只有在包头成功编译后,包体才能被编译。包体只包含包头中已预定义的子程序的代码。在包头中定义的对象可以直接在包体中使用,不必再包头中定义。 CREATE [OR REPLACE] PACKAGE BODY [schema.] package {IS|AS} pl/sql_bady; CREATE OR REPLACE PACKAGE BODY AuthsPack IS PROCEDURE QuerySalary(p_Code auths.author_code%TYPE,p_Salary auths.salary%TYPE) AS BEGIN SELECT salary INTO p_Salary FROM auths WHERE author_code= p_Code; END QuerySalary; PROCEDURE InsertAuthor(p_Code auths.author_code%TYPE,p_Name auths.name%TYPE); AS BEGIN INSERT INTO auths(author_code,name) VALUES(p_Code,p_Name); END InsertAuthor; END AuthsPack; 如果包头不包含存储过程和函数,则不必定义包体。如果包头中有预定义的子程序,则在包体中必须编写其子程序代码,而且包头和包体两部分指定的子程序必须一致,这包括相同的子程序名,参数名和参数类型。 1.3包的初始化 与变量类似,包也可以被初始化。只是初始化部分在包体的最后部分被定义。 语法: CREATE OR REPLACE PACKAGE BODY package {IS|AS} --包体中过程与函数的定义部分 BEGIN Initialization_code;--初始化代码 --QuerySalary('A0001',v_Salary); END [package]
2、包的使用
2.1包中对象的引用 在包中定义的任意对象都可以再保外使用,只是在引用该对象前用包名做前缀。 --设置缓冲区大小 SET SERVEROUTPUT ON SIZE 100000 DECLARE v_Salary auths.salary%TYPE; BEGIN AuthsPack.QuerySalary('A0001',v_Salary); DBMS_OUTPUT.PUT_LINE('工资为:'); DBMS_OUTPUT.PUT_LINE(v_Salary); END; 此存储过程的调用有包名作前缀。包中存储过程的参数也可以有缺省值,这些参数可通过位置表示法或命名表示法来调用。在包体内部不必带包名前缀即可直接引用包头中的对象。 2.2重载包中的子程序 在包的内部,存储过程和函数都可以被重载,这意味着有过个存储过程或函数可以使用同一个名称,但是参数不能相同。这样就允许用不同的参数调用同一个名字的过程或函数。 CREATE OR REPLACE AuthsPack AS PROCEDURE AddArticle(p_ArticleCode article.article_code%TYPE, p_AuthorCode article.author_code%TYPE); PROCEDURE AddArticle(p_Birthdate article.birthdate%TYPE, p_ArticleCode article.article_code%TYPE); END AuthsPack; CREATE OR REPLACE PACKAGE BODY ArticlePack IS PROCEDURE AddArticle(p_ArticleCode article.article_code%TYPE, p_AuthorCode article.author_code%TYPE) AS BEGIN INSERT INTO Article(Article_code,Author_code) VALUES(p_ArticleCode,p_AuthorCode); END AddArticle; PROCEDURE AddArticle(p_Birthdate article.birthdate%TYPE, p_ArticleCode article.article_code%TYPE) AS BEGIN INSERT INTO Article(Birthdate,Article_code) VALUES(p_Birthdate,p_AuthorCode); END AddArticle; END ArticlePack; 当仅仅参数名不同或者是模式不同时,不能重载子程序。 不能对仅有返回类型的函数进行重载。 重载函数的参数必须是数据类型不同或其类型间不可自动转换。 在定义包含违反上述限制的子程序的包时不会包编译错误。但是,允许PL/SQL引擎不能调用该子程序,会出现错误"PLS-307:too many daclarations of ’subprogram match this call."
3、在SQL语句中使用函数
4、系统提供的包DBMS_OUTPUT
Oracle8中,系统提供了一些包,这些包时在安装Oracle时自动安装的,用户可以直接使用。在内嵌包中有一个包经常用到--DBMS_OUTPUT,现在来简单地学习一下它。
内嵌包DBMS_OUTPUT用来输出PL/SQL变量的值。DBMS_OUTPUT包和其他系统包一样,都属于Oracle系统用户SYS内的对象。
作者:何海洋
本博客内容主要以学习、研究和分享为主,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。