Package是plsql语言中的一种对象。

和存储过程一样都是对象,之所以放在存储过程来说它,就是除了语法,基本上

没什么可说的。类比java,包package就是接口与实现类的关系。包package的出现

主要也是为了面向接口编程(个人理解)。你可以把java接口的知识类比学习包package。

里面可以放一些变量定义,方法定义,存储过程定义。


包package分为两大部分:包说明和包体。

包说明类似接口定义,包体类似实现类。


包说明的格式:

create or replace package ppppppppppppp is

  -- Author  : MY
  -- Created : 2013/7/11 16:19:16
  -- Purpose : 
  
  -- Public type declarations
  type <TypeName> is <Datatype>;
  
  -- Public constant declarations
  <ConstantName> constant <Datatype> := <Value>;

  -- Public variable declarations
  <VariableName> <Datatype>;

  -- Public function and procedure declarations
  function <FunctionName>(<Parameter> <Datatype>) return <Datatype>;

end ppppppppppppp;

 

包体的声明格式:

create or replace package body bbbbbbbbbbbbb is

  -- Private type declarations
  type <TypeName> is <Datatype>;
  
  -- Private constant declarations
  <ConstantName> constant <Datatype> := <Value>;

  -- Private variable declarations
  <VariableName> <Datatype>;

  -- Function and procedure implementations
  function <FunctionName>(<Parameter> <Datatype>) return <Datatype> is
    <LocalVariable> <Datatype>;
  begin
    <Statement>;
    return(<Result>);
  end;

begin
  -- Initialization
  <Statement>;
end bbbbbbbbbbbbb;

 

包说明和包体是1-0或1-1的关系。

如果只是声明变量,不涉及到方法和存储过程,那么只有包说明就可以正确编译和使用。

如果在包说明中除了定义变量还定义了其他的对象,像方法,存储过程。那就必须有包体,并在包体中实现定义的方法和存储过程。(这点和接口实现类很像,就是单继承和java接口不一样)。如果不实现,编译不报错,调用会报错。

包中对象的调用都是通过包名.变量名来调用。

到现在为止,包的好处和意义也应该清楚了。

首先,包的意义就是为了共享。这是一个编程很重要的问题。在java中,我们写一个类,

目的是为了调用。在其他地方,你可以直接new出来,就可以重复使用里面的方法,或者

这个类就是一种数据类型。这很容易理解。但是在plsql中我们声明一种自定义数据类型

(type),如果只在代码块的声明处定义,那就不能让其他对象共享。带来的问题就是如果返回结果是这种类型,怎么让其他对象认识?

有了包,就使得plsql更像编程而不是简单的sql语句组合。

其次,包的结构类似java中的接口。这种设计的好处你可以认为就是面向接口编程的好处。

(注意,包体中实现包说明中的定义时,必须和声明一模一样!包括变量的名字!)

 



包说明:

 

create or replace package lsy_package is

  --类型
  type type_myrecord1 is record(
    r_codecode lsy_codebook.codecode%type not null := 'i am default value',
    r_codename lsy_codebook.codename%type,
    r_result   varchar2(32) default null,
    r_flag     number default 0);

  --constant变量声明(必须赋值,类似java中final)
  date_pattern_str constant varchar2(32) := 'yyyy-mm-dd hh24:mi:ss';
  --变量声明
  v_pub_yes  varchar2(32) := 'yes';

  myexception_package_one exception; --异常
  procedure procc(ppp in number); --存储过程
  function funcff(fff in number) return number; --方法

end lsy_package;

 

包体:

create or replace package body lsy_package is

  -- 私有的类型type声明
  type body_type is record(
    r_one varchar2(32) not null := '',
    r_two number);

  -- 私有的constant变量声明
  pub_body_true constant varchar2(32) := '1';
  pub_body_false constant varchar2(32) := '0';

  -- 私有的变量声明
  v_now     date := sysdate;
  v_now_str varchar2(32);

  -- 实现继承的方法和存储过程(也可以有私有的,那样只能在包体中使用,不能被调用)
  procedure procc(ppp in number) is
    rr number;
  begin
    rr := ppp + 1;
    dbms_output.put_line('procc被调用:' || rr);
  exception
    when myexception_package_one then
      raise_application_error(-20000,
                              'lsy_package中自定义异常:xxx!',
                              false);
    when others then
      raise;
  end procc;
  --
  function funcff(fff in number) return number is
    res number;
  begin
    res := fff + 1;
    dbms_output.put_line('funcff被调用:' || res);
    return res;
  end;

begin
  --在第一次调用时这个代码块只走一次
  v_now_str := to_char(v_now, date_pattern_str);
  dbms_output.put_line('初始化时间:' || v_now_str);
end lsy_package;

 

匿名代码块测试;

-- Created on 2013/7/11 by lsy 
-- package测试1
declare
  v_one lsy_package.type_myrecord1;
begin
  v_one.r_codecode := 'qq';
  v_one.r_codename :='ww';
  v_one.r_result:='success!';
  v_one.r_flag:=1;
  dbms_output.put_line('v_one.r_codecode:' ||
                       v_one.r_codecode ||
                       ',v_one.r_codename:' ||
                       v_one.r_codename||
                       ',v_one.r_result:'||v_one.r_result||
                       ',v_one.r_flag:'||v_one.r_flag);
                       
  dbms_output.put_line('lsy_package.date_pattern_str:' ||lsy_package.date_pattern_str );
  dbms_output.put_line('lsy_package.v_pub_yes:' ||lsy_package.v_pub_yes );
  
  dbms_output.put_line('lsy_package.funcff(3):' ||lsy_package.funcff(3) );
  
  lsy_package.procc(1);
  
end;

/*打印
v_one.r_codecode:qq,v_one.r_codename:ww,v_one.r_result:success!,v_one.r_flag:1
lsy_package.date_pattern_str:yyyy-mm-dd hh24:mi:ss
lsy_package.v_pub_yes:yes
funcff被调用:4
lsy_package.funcff(3):4
procc被调用:2

*/