zoukankan      html  css  js  c++  java
  • oracle type类型

    转载 http://blog.sina.com.cn/s/blog_6cfb6b090100ve92.html

    转自网络,具体用法我会再细化

    1.概念  
      方法:是在对象类型说明中用关键字  MEMBER   声明的子程序    
      方法是作为对象类型定义组成部分的一个过程或函数    
      方法不能与对象类型或其任何属性同名    
      与数据包程序相似,大多数方法有两个部分  
       
    CREATE   [OR   REPLACE]   TYPE   <typename>   AS   OBJECT(attribute1   datatype,   :   attributeN   datatypeMEMBER   PROCEDURE   <methodname>   (parameter,   mode,   datatype),MEMBER   FUNCTION   <methodname>   (parameter,   mode,   datatype)   RETURN   datatype,PRAGMA   RESTRICT_REFERENCES   (<methodname>,WNDS/RNDS/WNPS/RNPS));  
      说明:PRAGMA   RESTRICT_REFERENCES指定MEMBER方法按以下模式之一   操作:
       –WNDS   (不能写入数据库状态)   不能修改数据库    
      –RNDS   (不能读出数据库状态)   不能执行查询    
      –WNPS   (不能写入数据包状态)   不能更改数据包变量的值    
      –RNPS   (不能读出数据包状态)   不能引用数据包变量的值    
      例:create   or   replace   type   FLIGHT_SCH_TYPE   as   object
          (FLIGHTNO   VARCHAR2(4)   ,   AIRBUSNO   VARCHAR2(5)   ,
           ROUTE_CODE   VARCHAR2(7)   ,   DEPRT_TIME   VARCHAR2(10)   ,
           JOURNEY_HURS   VARCHAR2(10)   ,   FLIGHT_DAY1   NUMBER(1)   , 
           FLIGHT_DAY2   NUMBER(1)   ,  
           Member   function   DAYS_FN(FLIGHT_DAY1   in   number)   return   varchar2   ,
           Pragma       restrict_references(DAYS_FN   ,   WNDS))   ;  
       
      2.创建对象类型方法主体
    CREATE   [OR   REPLACE]   TYPE   BODY   <typename>   ASMEMBER   FUNCTION   <methodname>   (parameter   dataype)   RETURN   <datatype>   IS<PL/SQL_block>;MEMBER   PROCEDURE   <methodname>(parameter   datatype);END;  
      例:create   or   replace   type   body   FLIGHT_SCH_TYPE   as 
           member   function   DAYS_FN(FLIGHT_DAY1   in   number)   return   varchar2
           is 
          disp_day   varchar2(20)   ;
          begin      
          if   flight_day1   =   1   then 
               disp_day   :=   'Sunday'   ;         
         elsif   flight_day1   =   2   then   
               disp_day   :=   'Monday'   ;          
         elsif   flight_day1   =   3   then      
              disp_day   :=   'Tuesday'   ;       
         elsif   flight_day1   =   4   then      
             disp_day   :=   'Wednesday'   ;       
         elsif   flight_day1   =   5   then        
             disp_day   :=   'Thursday'   ;           
        elsif   flight_day1   =   6   then          
             disp_day   :=   'Friday   '   ;     
           elsif   flight_day1   =   7   then   
             disp_day   :=   'Saturday'   ;    
        end   if   ;           
         return   disp_day   ;   
      end   ;
    end   ; 
    3.调用对象方法基于类型创建表后,就可以在查询中调用对象方法  
       
      A. 创建基于对象的表语法:
    create   table   <表名>   of   <对象类型>意义:此表具有该类型和member方法的所有属性,
    我们不能通过DBA   STUDIO的表数据编辑器来编辑数据。
    例:create   table   FLIGHT_SCH_TAB   of   FLIGHT_SCH_TYPE 
        insert   into   FLIGHT_SCH_TAB     values('SL36','AB02','SAN-LOU','5','13:30',3,6);  
       
      B.访问对象表中的MEMBER方法
    SELECT   <columnname>,   <aliasname>.<methodname(parameters)>FROM   <tablename>   <aliasname>;
    例:select   flightno,route_code,f.days_fn(flight_day1) as  FLIGHTDAY from FLIGHT_SCH_TAB  f;

        
      C.关系表中的字段为对象类型
    create   table   FLIGHT_SCH_TABS(FLIGHT_DET   FLIGHT_SCH_TYPE   ,     FLIGHT_DESC   varchar2(20))   ;
    注:插入数据,对于对象类型的字段的值,需要通过构造函数来得到。对象类型名称(成员1,..成员n)
    例:insert   into   FLIGHT_SCH_TABS     values(FLIGHT_SCH_TYPE('SL36','AB02','SAN-LOU','5','13:30',3,6),'DESC1');  
       
      D.访问关系表中的Member方法此处的关系表:指表中有字段为对象类型
    SELECT   <columnname>,   <aliasname>.<columnname>.<methodname (parameters)>FROM   <tablename>   <aliasname>;
    例:select f.flight_det.FLIGHTNO,f.flight_det.ROUTE_CODE,f.flight_det.DAYS_FN(f.flight_det.FLIGHT_DAY1) FLIGHTDAY from flight_sch_tabs f;
    1. 声明简单类型内容包括:A   对象类型的创建B.基于对象的表的创建插入与访问C   关系对象表的创建插入与访问  
       
      2. 通过value运算符访问基于类型的表
    select   value(<aliasname>     From   <objecttable>   <aliasname>
    例:select   value(A)   FROM   FLIGHT_SCH_TAB    
       
      A   --返回的是对象区别
    select   *   from   FLIGHT_SCH_TAB;--返回的是单个的值  
       
      3. REF   运算符使您可以引用对象表中现有行的   OID   值   REF   运算符将表别名作为输入,并且为行对象返回   OID  
        语法:select   REF(<aliasname>)   from   <objecttable>   <aliasname>
    例:select   ref(a)   from   FLIGHT_SCH_TAB   a   ;注:FLIGHT_SCH_TAB   是基于对象的表  
       
      4.声明复合类型
    CREATE   TYPE   name_type AS   OBJECT(name   VARCHAR2(20),   address   address_type);  
      5.定义对象之间的关系也是通过关键字REF,前面我们能过REF查询了基于对象的表中的对象的OID值,这里我们讲REF的另一个用途,即通过REF来定义对象之间的关系  
      称为引用的   REF   允许您创建行对象指针  
      它将创建对被引用对象位置的引用i该指针用于查询、更新或删除对象iREF   由目标对象的   OID、数据库标识符(列)和对象表构成iOID   用于创建使用   REF   和   DEREF   运算符的外键列的关系  
      iSQL   和   PL/SQL   语句必须使用   REF   函数来处理对象引用    
      可按如下步骤关联两个表  
       
      1. 创建对象类型,下面我们会创建另一个表,这个表的一个字段的类型为此类型
    create   or   replace   type   type_class   as   object(     classid   varchar2(10)   ,     classname   varchar2(10))/  
       
      2. 创建基于此类型的表create     table   tbl_type_class   of   type_class      
       
      3. 创建具有外键列的关系表,有一个外键将引用1中定义的类型,并且该外键的值在2中已有的数据已经存在create   table   tbl_student_ref(     stuid   varchar2(20)   ,     stuname   varchar2(20)   ,     age   number(10)   ,     grade   ref   type_class   scope   is   tbl_type_class)  
       
      4. 将数据插入到对象表中begin     insert   into   tbl_type_class   values('gid1'   ,   'gname1')   ;
           insert   into   tbl_type_class   values('gid2'   ,   'gname2')   ;     commit   ;end   ;/  
       
      5.将数据插入到关系对象表中,必须从上面创建的对象表中引用数据;  
    insert   into   tbl_student_ref     select       'stuid1',   'stuname1',20,ref(a)         from   tbl_type_class   a         where   classid='gid1'
    注:下面的方法是不行的!insert   into   tbl_student_ref   values(     'stuid2',     'stuname2',     20,     select   ref(a)   from   tbl_type_class   a   where   classid='gid1'   )/  
       
      6.服从值若要查看引用的值,则需要使用DEREF运算符i语法SELECT   DEREF(<列名>.<列名>)FROM   <表名>   <别名>;例:select   deref(grade)   from   tbl_student_ref

    一、抽象数据类型
    1、创建类型
    --地址类型
    CREATE OR REPLACE TYPE AddressType AS OBJECT
    (
    Country varchar2(15),
    City varchar2(20),
    Street varchar2(30)
    );

    2、类型嵌套
    --创建基于前一个类型的新的抽象数据类型:巨星类型
    CREATE OR REPLACE TYPE SuperStarType AS OBJECT
    (
    StarName varchar2(30),
    Address AddressType
    );

    3、基于抽象类型创建关系表
    CREATE TABLE SuperStar
    (
    StarID varchar(10),
    Star SuperStarType
    );

    4、基于抽象类型创建对象表
    CREATE TABLE SuperStarObj of SuperStarType;

    5、使用构造方法在表中插入记录
    INSERT INTO SuperStar VALUES(''001'',SuperStarType(''Zidane'',AddressType(''France'',''Paris'',''People Street NO.1'')));

    6、查询表中记录
    (1)SQL> SELECT * FROM SuperStar;

    STARID
    ----------
    STAR(STARNAME, ADDRESS(COUNTRY, CITY, STREET))
    --------------------------------------------------------------------------------
    001
    SUPERSTARTYPE(''Zidane'', ADDRESSTYPE(''France'', ''Paris'', ''People Street NO.1''))

    (2)
    SELECT s.StarID,s.Star.StarName,s.Star.Address.Country,s.Star.Address.City,s.Star.Address.Street FROM SuperStar s

    STARID STAR.STARNAME STAR.ADDRESS.CO STAR.ADDRESS.CITY STAR.ADDRESS.STREET
    ---------- ------------------------------ --------------- -------------------- ---------------------
    001 Zidane France Paris People Street NO.1

    7、抽象数据类型的继承
    (1)创建一个类型
    CREATE OR REPLACE TYPE PersonType AS OBJECT
    (
    PersonName varchar(10),
    PersonSex varchar(2),
    PersonBirth date
    ) not final;
    (2)派生一个类型
    CREATE OR REPLACE TYPE StudentType UNDER PersonType
    (
    StudentNO int,
    StudentScore int
    );
    (3)查看数据字典
    SQL> DESC StudentType
    StudentType extends SYS.PERSONTYPE
    Name
    ------------------------------------------------------------------------------
    PERSONNAME
    PERSONSEX
    PERSONBIRTH
    STUDENTNO
    STUDENTSCORE
    (4)创建对象表
    CREATE TABLE student OF StudentType;
    (5)向对象表中插入数据
    INSERT INTO student VALUES(''Rose'',''nv'',to_date(''1983-05-02'',''yyyy-mm-dd''),1001,98);
    (6) 查询数据
    SQL> SELECT * FROM student;

    PERSONNAME PE PERSONBIR STUDENTNO STUDENTSCORE
    ---------- -- --------- ---------- ------------
    Rose nv 02-MAY-83 1001 98

    二、可变数组
    1、创建带有可变数组的表
    (1)创建可变数组的基类型
    CREATE OR REPLACE TYPE MingXiType AS OBJECT
    (
    GoodID varchar2(20),
    InCount int,
    ProviderID varchar(20)
    );
    (2)创建嵌套项类型的可变数组
    CREATE OR REPLACE TYPE arrMingXiType AS VARRAY(100) OF MingXiType;
    (3)创建一个主表
    CREATE TABLE InStockOrder
    (
    OrderID varchar(15) Not Null Primary Key,
    InDate date,
    OperatorID varchar(15),
    MingXi arrMingXiType
    );

    2、操作可变数组
    (1)插入数据
    INSERT INTO InStockOrder
    VALUES(''200710110001'',TO_DATE(''2007-10-11'',''YYYY-MM-DD''),''007'',
    arrMingXiType(MingXiType(''G001'',100,''1001''),
    MingXiType(''G002'',888,''1002''))
    );
    (2)查询数据
    SQL> SELECT * FROM InStockOrder;

    ORDERID INDATE OPERATORID
    --------------- --------- ---------------
    MINGXI(GOODID, INCOUNT, PROVIDERID)
    ----------------------------------------------------------------------
    200710110001 11-OCT-07 007
    ARRMINGXITYPE(MINGXITYPE(''G001'', 100, ''1001''), MINGXITYPE(''G002'', 888, ''1002'')
    (3)使用Table()函数
    SQL> SELECT * FROM Table(SELECT t.MingXi FROM InStockOrder t
    WHERE t.OrderID=''200710110001'');

    GOODID INCOUNT PROVIDERID
    -------------------- ---------- --------------------
    G001 100 1001
    G002 888 1002
    (4)修改数据
    UPDATE InStockOrder
    SET MingXi=arrMingXiType(MingXiType(''G001'',200,''1001''),
    MingXiType(''G002'',8888,''1002''))
    WHERE OrderID=''200710110001''
    注意:不能更新VARRAY中的单个元素,必须更新整个VARRAY

    三、嵌套表
    1、创建嵌套表
    (1)创建嵌套表的基类型
    CREATE OR REPLACE TYPE MingXiType AS OBJECT
    (
    GoodID varchar2(20),
    InCount int,
    ProviderID varchar(20)
    ) not final;
    (2)创建嵌套表类型
    CREATE OR REPLACE TYPE nestMingXiType AS TABLE OF MingXiType;
    (3)创建主表,其中一列是嵌套表类型
    CREATE TABLE InStockTable
    (
    OrderID varchar(15) Not Null Primary Key,
    InDate date,
    OperatorID varchar(15),
    MingXi nestMingXiType
    ) Nested Table MingXi STORE AS MingXiTable;

    2、操作嵌套表
    (1)向嵌套表中插入记录
    INSERT INTO InStockTable
    VALUES(''20071012001'',TO_DATE(''2007-10-12'',''YYYY-MM-DD''),''007'',
    nestMingXiType(MingXiType(''G003'',666,''1001''),
    MingXiType(''G004'',888,''1002''),
    MingXiType(''G005'',8888,''1003''))
    );
    (2)查询数据
    SQL> SELECT * FROM InStockTable;

    ORDERID INDATE OPERATORID
    --------------- --------- ---------------
    MINGXI(GOODID, INCOUNT, PROVIDERID)
    ----------------------------------------------------------------------------------------------------
    20071012001 12-OCT-07 007
    NESTMINGXITYPE(MINGXITYPE(''G003'', 666, ''1001''), MINGXITYPE(''G004'', 888, ''1002''), MINGXITYPE(''G005'', 8888, ''1003'')
    (3)使用Table()函数
    SQL> SELECT * FROM Table(SELECT T.MingXi FROM InStockTable t
    WHERE OrderID=''20071012001'')

    GOODID INCOUNT PROVIDERID
    -------------------- ---------- --------------------
    G003 666 1001
    G004 888 1002
    G005 8888 1003
    (4)更新嵌套表中的数据
    UPDATE Table(SELECT t.MingXi FROM InStockTable t WHERE OrderID=''20071012001'') tt
    SET tt.InCount=1666 WHERE tt.GoodID=''G003'';
    (5)删除表中数据
    DELETE Table(SELECT t.MingXi FROM InStockTable t WHERE OrderID=''20071012001'') tt
    WHERE tt.GoodID=''G003''

    四、对象表
    1、创建对象表
    CREATE TABLE ObjectTable OF MingXiType;
    2、向表中插入数据
    INSERT INTO ObjectTable VALUES(''G001'',500,''P005'');

    INSERT INTO ObjectTable VALUES(''G002'',1000,''P008'');
    3、查询对象表中的记录
    A 直接查询
    SQL> SELECT * FROM ObjectTable;

    GOODID INCOUNT PROVIDERID
    -------------------- ---------- ---------------
    G001 500 P005
    G002 1000 P008
    B 用VALUE()函数查询
    SQL> SELECT VALUE(O) FROM ObjectTable O;

    VALUE(O)(GOODID, INCOUNT, PROVIDERID)
    ------------------------------------------
    MINGXITYPE(''G001'', 500, ''P005'')
    MINGXITYPE(''G002'', 1000, ''P008'')
    4、查看对象标志符(OID)
    A REF操作符引用行对象
    SQL> SELECT REF(t) FROM ObjectTable t;

    REF(T)
    --------------------------------------------------------------------------------
    0000280209771F103ED34842478A9C439CDAEFEF6324B0ACF849F14BD7A8B52F4B0297D1C90040A9
    5A0000

    0000280209A2D3359E0F0C44B3AF652B944F8823F524B0ACF849F14BD7A8B52F4B0297D1C90040A9
    5A0001
    B 将OID用于创建外键
    CREATE TABLE Customer
    ( CustomerID varchar(10) PRIMARY KEY,
    CustomerName varchar(20),
    CustomerGoods REF MingXiType SCOPE IS ObjectTable,--引用MingXiType外键,关联的是OID的值
    CustomerAddress varchar(20)
    );
    C 向Customer表中插入数据,此表将从上面创建的对象表中引用数据
    INSERT INTO Customer SELECT ''007'',''Yuanhy'',REF(O),''France''
    FROM ObjectTable O
    WHERE GoodID=''G001'';
    D 查询Customer表
    SQL> SELECT * FROM Customer;

    CUSTOMERID CUSTOMERNAME
    ---------- --------------------
    CUSTOMERGOODS
    -----------------------------------------------------------------------------
    CUSTOMERADDRESS
    --------------------
    007 Yuanhy
    0000220208771F103ED34842478A9C439CDAEFEF6324B0ACF849F14BD7A8B52F4B0297D1C9
    France
    E 用DEREF操作符返回对象的值
    SQL> SELECT CustomerID,CustomerName,DEREF(t.CustomerGoods),CustomerAddress
    2 FROM Customer t;

    CUSTOMERID CUSTOMERNAME
    ---------- --------------------
    DEREF(T.CUSTOMERGOODS)(GOODID, INCOUNT, PROVIDERID)
    ----------------------------------------------------------------------------
    CUSTOMERADDRESS
    --------------------
    007 Yuanhy
    MINGXITYPE(''G001'', 500, ''P005'')
    France

    五、对象视图
    将关系表化装成对象表
    1、 创建对象视图
    A 创建基于关系表父表的对象类型
    CREATE OR REPLACE TYPE depttype AS OBJECT
    (
    deptid number(10),
    deptname varchar(30),
    loc number(10)
    );
    B 创建基于关系表的对象视图
    CREATE VIEW deptview OF depttype WITH OBJECT OID(deptid) AS
    SELECT department_id,department_name,location_id FROM dept;
    C 查询视图
    SQL> SELECT * FROM deptview;

    DEPTID DEPTNAME LOC
    ---------- ------------------------------ ----------
    10 Administration 1700
    20 Marketing 1800
    30 Purchasing 1700
    40 Human Resources 2400
    50 Shipping 1500
    60 IT 1400
    70 Public Relations 2700

    SQL> select ref(t) from deptview t;

    REF(T)
    ----------------------------------------------------------------------------------------------------
    00004A038A004667BAC3685B444520A60ED30027E8F25F0000001426010001000100290000000000090604002A00078401FE
    00004A038A004667BAC3685B444520A60ED30027E8F25F0000001426010001000100290000000000090604002A00078401FE
    00004A038A004667BAC3685B444520A60ED30027E8F25F0000001426010001000100290000000000090604002A00078401FE
    00004A038A004667BAC3685B444520A60ED30027E8F25F0000001426010001000100290000000000090604002A00078401FE
    00004A038A004667BAC3685B444520A60ED30027E8F25F0000001426010001000100290000000000090604002A00078401FE
    00004A038A004667BAC3685B444520A60ED30027E8F25F0000001426010001000100290000000000090604002A00078401FE
    00004A038A004667BAC3685B444520A60ED30027E8F25F0000001426010001000100290000000000090604002A00078401FE
    2、创建引用视图(类似于关系表创建一个从表)
    CREATE VIEW empview AS SELECT MAKE_REF(deptview,department_id) deptOID,employee_id,
    first_name,last_name FROM emp;

    查询对象视图empview
    SQL> SELECT * FROM empview;

    DEPTOID
    ----------------------------------------------------------------------------------------------------
    EMPLOYEE_ID FIRST_NAME LAST_NAME
    ----------- -------------------- -------------------------
    00004A038A004667BAC3685B444520A60ED30027E8F25F0000001426010001000100290000000000090604002A00078401FE
    100 Steven King

    00004A038A004667BAC3685B444520A60ED30027E8F25F0000001426010001000100290000000000090604002A00078401FE
    101 Neena Kochhar

    00004A038A004667BAC3685B444520A60ED30027E8F25F0000001426010001000100290000000000090604002A00078401FE
    102 Lex De Haan

    00004A038A004667BAC3685B444520A60ED30027E8F25F0000001426010001000100290000000000090604002A00078401FE
    103 Alexander Hunold
    Oracle对象类型也有属性和方法.
      创建对象类型与创建表很相似,只是实际上不为存储的数据分配空间:
      不带方法的简单对象类型:

    CREATE TYPE type_name as OBJECT (
    column_1 type1,
    column_2 type2,
    ...
    );
      注意:AS OBJECT
      创建好对象类型之后,就可以在创建表的时候,使用该类型了,如:

    CREATE TYPE HUMAN AS OBJECT(
    NAME VARCHAR2(20),
    SEX VARCHAR2(1),-- F : FEMALE M:MALE
    BIRTHDAY DATE,
    NOTE VARCHAR2(300)
    )
      稍后,可以用下面的语句查看:

    SELECT * FROM USER_OBJECTS WHERE OBJECT_TYPE = ''TYPE''
    CREATE TABLE STUDENTS(
    GUID NUMBER NOT NULL,
    STUDENTS HUMAN
    )
      此下省去两个Trigger.
      插入数据的时候,可以如下:

    INSERT INTO STUDENTS (STUDENT) VALUES (HUMAN(''xling'',''M'',TO_DATE(''20060101'',''YYYYMMDD''),''测试''))
      注意:HUMAN(''xling'',''M'',TO_DATE(''20060101'',''YYYYMMDD''),''测试''),这是个默认的构造函数.
      如果想选出性别为女(F)的记录,可以如下:

    SELECT * FROM STUDENTS S WHERE S.STUDENT.SEX = ''F''
      注意:不能写成:SELECT * FROM STUDENTS WHERE STUDENT.SEX = ''F'' 这样会报如下错误:ORA-00904: "STUDENT"."SEX": 标识符无效

      对象类型表:每条记录都是对象的表,称为对象类型表.它有两个使用方法:1,用作只有一个对象类型字段的表.2,用作具有对象类型字段的标准关系表.
      语法如下:

    CREATE TABLE table_name OF object_type;
      例如:

    CREATE TABLE TMP_STUDENTS OF HUMAN;
      用DESC TMP_STUDENTS,可以看到它的字段结构和HUMAN的结构一样.
      对象类型表有两个优点:1,从某种程度上简化了对象的使用,因为对象表的字段类型与对象类型是一致的,所以,不需要用对象名来修饰对象属性,可以把数据插入对象类型表,就像插入普通的关系表中一样:
    INSERT INTO TMP_STUDENTS VALUES (''xling'',''M'',TO_DATE(''20060601'',''YYYYMMDD''),''对象类型表'');
      当然也可用如下方法插入:
    INSERT INTO TMP_STUDENTS VALUES (HUMAN(''snow'',''F'',TO_DATE(''20060102'',''YYYYMMDD''),''用类型的构造函数''));
      第二个特点是:对象表是使用对象类型作为模板来创建表的一种便捷方式,它可以确保多个表具有相同的结构.
      对象类型表在:USER_TABLES表里是查不到的,而在USER_OBJECTS表里可以查到,而且OBJECT_TYPE = ''TABLE''
      类型在定义的时候,会自动包含一个方法,即默认的构造器.构造器的名称与对象的名称相同,它带有变量与对象类型的每个属性相对应.

      对象类型的方法:

    CREATE TYPE type_name AS OBJECT (
    column1 column_type1,
    column2 column_type2,
    ... ,
    MEMBER FUNCTION method_name(args_list) RETURN return_type,
    ...
    )
      注意:是MEMBER FUNCTION,(当然,也可是MEMBER PROCEDURE,没有返回值)
      和包(PACKAGE)一样,如果对象类型有方法的话,还要声明一个BODY:

    CREATE TYPE BODY type_name AS

    MEMBER FUNCTION method_name RETURN return_type {AS | IS}
    variable declareations..
    BEGIN
    CODE..
    RETURN return_value;
    END;//END MEMBER FUNCTION
    ...
    END;//END TYPE BODY
      如下所示:

    CREATE TYPE HUMAN AS OBJECT(
    NAME VARCHAR2(20),
    SEX VARCHAR2(1),-- F : FEMALE M:MALE
    BIRTHDAY DATE,
    NOTE VARCHAR2(300),

    MEMBER FUNCTION GET_AGE RETURN NUMBER
    )
    --BODY
    CREATE TYPE BODY HUMAN AS
    MEMBER FUNCTION GET_AGE RETURN NUMBER AS
    V_MONTHS NUMBER;
    BEGIN
    SELECT FLOOR(MONTHS_BETWEEN(SYSDATE,BIRTHDAY)/12) INTO V_MONTHS FROM DUAL;
    RETURN V_MONTHS;
    END;
    END;

      
      注意:BODY的格式,不是AS OBJECT,也不是用小括号括起来的.MEMBER FUNCTION 后的AS或IS不能省略.
      还以STUDENTS表为例(注:如果类型以被某个表使用,是不能修改的,必须把相关的表删除,然后把类型删除,在一个一个新建,这里就省略了,参见前文所述)
    SELECT S.STUDENT.GET_AGE() FROM STUDENTS S
      
      在提起注意:表名一定要有别名.GET_AGE()的括号不能省略,否则会提示错误.
      下面演示在一个匿名过程中的使用情况:
    SET SERVEROUTPUT ON
    DECLARE
    AA HUMAN;
    AGE NUMBER;
    BEGIN
    AA := HUMAN(''xingFairy'',''M'',TO_DATE(''19830714'',''YYYYMMDD''),''过程'');
    AGE := AA.GET_AGE();
    DBMS_OUTPUT.PUT_LINE(AGE);
    END;
      映射方法:
      映射方法是一种不带参数,并返回标准的标量Oracle SQL数据类型的方法,如NUMBER,VARCHAR2,Oracle将间接地使用这些方法执行比较运算.
      映射方法最重要的一个特点是:当在WHERE或ORDER BY等比较关系子句中使用对象时,会间接地使用映射方法.
      映射方法的声明只过是在普通方法声明的前面加一个 MAP而以,注意:映射方法是一种不带参数的方法.
    MAP MEMBER FUNCTION function_name RETURN return_type
      修改前文提到的HUMAN类型:
    --映射方法 MAP

    CREATE TYPE HUMAN AS OBJECT(
    NAME VARCHAR2(20),
    SEX VARCHAR2(1),-- F : FEMALE M:MALE
    BIRTHDAY DATE,--注册日期 
    REGISTERDAY DATE,
    NOTE VARCHAR2(300),

    MEMBER FUNCTION GET_AGE RETURN NUMBER,
    MAP MEMBER FUNCTION GET_GRADE RETURN NUMBER
    )
    CREATE TYPE BODY HUMAN AS
    -----------------------
    MEMBER FUNCTION GET_AGE RETURN NUMBER AS
    V_MONTHS NUMBER;
    BEGIN
    SELECT FLOOR(MONTHS_BETWEEN(SYSDATE,BIRTHDAY)/12) INTO V_MONTHS FROM DUAL;
    RETURN V_MONTHS;
    END;
    ------------------------
    MAP MEMBER FUNCTION GET_GRADE RETURN NUMBER AS
    BEGIN
    RETURN MONTHS_BETWEEN(SYSDATE,BIRTHDAY);
    END;
    END;
      插入数据:

    INSERT INTO STUDENTS (STUDENT) VALUES (HUMAN(''xling'',''M'',TO_DATE(''19830714'',''YYYYMMDD''),TO_DATE(''20020915'',''YYYYMMDD''),'' 测试MAP方法''));
    INSERT INTO STUDENTS (STUDENT) VALUES (HUMAN(''fairy'',''M'',TO_DATE(''19830714'',''YYYYMMDD''),TO_DATE(''20010915'',''YYYYMMDD''),'' 测试MAP方法''));
    INSERT INTO STUDENTS (STUDENT) VALUES (HUMAN(''snow'',''M'',TO_DATE(''19830714'',''YYYYMMDD''),TO_DATE(''20020915'',''YYYYMMDD''),'' 测试MAP方法''));
      在执行上面的操作后,用下面这个SELECT语句可以看出映射方法的效果:
    SELECT S.STUDENT.NAME,S.STUDENT.GET_GRADE() FROM STUDENTS S ORDER BY STUDENT
      它是按MAP方法GET_GRADE()的值进行排序的.注意是ORDER BY STUDENT,在提起一次需要注意,一定要用表的别名,方法后的括号不能省略,即使没有参数.
      如果想以MAP方法的结果为条件,可以如下:

    SELECT S.STUDENT.NAME,S.STUDENT.GET_GRADE() FROM STUDENTS S WHERE S.STUDENT.GET_GRADE() > 50
    SELECT S.STUDENT.NAME,S.STUDENT.GET_GRADE() FROM STUDENTS S WHERE STUDENT > HUMAN(NULL,NULL,NULL,TO_DATE(''20020101'',''YYYYMMDD''),NULL);
      排序方法:
      先说一下SELF,Oracle里对象的SELF和JAVA里的this是同一个意思.
      对象的排序方法具有一个与对象类型相同的参数,暂称为ARG1,用于和SELF对象进行比较.如果调用方法的SELF对象比ARG1小,返回负值,如果相等,返回0,如果SELF大于ARG1,则返回值大于0.
    --映射方法 MAP

    CREATE TYPE HUMAN AS OBJECT(
    NAME VARCHAR2(20),
    SEX VARCHAR2(1),-- F : FEMALE M:MALE
    BIRTHDAY DATE,
    REGISTERDAY DATE,
    NOTE VARCHAR2(300),

    MEMBER FUNCTION GET_AGE RETURN NUMBER,
    ORDER MEMBER FUNCTION MATCH(I_STUDENT IN HUMAN) RETURN NUMBER
    )
    CREATE TYPE BODY HUMAN AS
    -----------------------
    MEMBER FUNCTION GET_AGE RETURN NUMBER AS
    V_MONTHS NUMBER;
    BEGIN
    SELECT FLOOR(MONTHS_BETWEEN(SYSDATE,BIRTHDAY)/12) INTO V_MONTHS FROM DUAL;
    RETURN V_MONTHS;
    END;
    ------------------------
    ORDER MEMBER FUNCTION MATCH(I_STUDENT IN HUMAN) RETURN NUMBER AS
    BEGIN
    RETURN REGISTERDAY - I_STUDENT.REGISTERDAY;
    END;
    END;
      注意:在声明的时候,ORDER方法的参数类型要和SELF的类型一致.
    SET SERVEROUTPUT ON
    DECLARE
    S1 HUMAN;
    S2 HUMAN;
    BEGIN

    S1 := HUMAN(''xling'',NULL,NULL,TO_DATE(''20020915'',''YYYYMMDD''),NULL);
    S2 := HUMAN(''snow'',NULL,NULL,TO_DATE(''20010915'',''YYYYMMDD''),NULL);

    IF S1 > S2 THEN
    DBMS_OUTPUT.PUT_LINE(S1.NAME);
    ELSIF S1 < S2 THEN
    DBMS_OUTPUT.PUT_LINE(S2.NAME);
    ELSE
    DBMS_OUTPUT.PUT_LINE(''EQUAL'');
    END IF;
    END;
      注意S1 和 S2是怎么比较的.
      映射方法具有效率方面的优势,因为它把每个对象与单个标量值联系在一起;排序方法有灵活方面的优势,它可以在两个对象之间进行任意复杂的比较.排序方法比映射方法的速度慢.
  • 相关阅读:
    我的WCF之旅(1):创建一个简单的WCF程序
    网页设计中颜色的搭配
    CSS HACK:全面兼容IE6/IE7/IE8/FF的CSS HACK
    UVa 1326 Jurassic Remains
    UVa 10340 All in All
    UVa 673 Parentheses Balance
    UVa 442 Matrix Chain Multiplication
    UVa 10970 Big Chocolate
    UVa 679 Dropping Balls
    UVa 133 The Dole Queue
  • 原文地址:https://www.cnblogs.com/meimao5211/p/3382956.html
Copyright © 2011-2022 走看看