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是怎么比較的.
  映射方法具有效率方面的優勢,因為它把每個對象與單個標量值聯系在一起;排序方法有靈活方面的優勢,它可以在兩個對象之間進行任意復雜的比較.排序方法比映射方法的速度慢.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM