• 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是怎么比较的.
      映射方法具有效率方面的优势,因为它把每个对象与单个标量值联系在一起;排序方法有灵活方面的优势,它可以在两个对象之间进行任意复杂的比较.排序方法比映射方法的速度慢.
  • 相关阅读:
    10个对Web开发者最有用的Python包
    9款最好的JavaScript压缩工具
    推荐15款制作 SVG 动画的 JavaScript 库
    2016年最好的15个Web设计和开发工具
    整理六百篇web前端知识混总
    9款免费的跨浏览器测试工具
    9个有用的和免费的工具来支持动态网页开发
    8个基本的引导工具的网页设计师
    11款CSS3动画工具的开发
    2016年某前端群题目答案参考
  • 原文地址:https://www.cnblogs.com/future2012lg/p/2866727.html
Copyright © 2020-2023  润新知