Oracle自定义数据类型 2 (调用对象方法)

原博客地址:https://www.cnblogs.com/arxive/p/6005886.html

 

调用对象方法

调用对象方法基于类型创建表后,就可以在查询中调用对象方法

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>;

例1 

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运算符

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

简单用法:

复制代码
create or replace type typ_calendar as object(
    年 varchar2(8), 月 varchar2(8), 星期日 varchar2(8), 星期一 varchar2(8), 星期二 varchar2(8), 星期三 varchar2(8), 星期四 varchar2(8), 星期五 varchar2(8), 星期六 varchar2(8), 本月最后一日 varchar2(2) ); --这种类型可以在表结构定义的时候使用: create table tcalendar of typ_calendar; --插入数据测试: SQL> insert into tcalendar 2 select typ_calendar('2010','05','1','2','3','4','5','6','7','31') from dual 3 / --注意:插入的数据需要用typ_calendar进行转换。 1 row inserted --查看结果 SQL> select * from tcalendar; 年 月 星期日 星期一 星期二 星期三 星期四 星期五 星期六 本月最后一日 -------- -------- -------- -------- -------- -------- -------- -------- -------- ------------ 2010 05 1 2 3 4 5 6 7 31
复制代码

复杂用法如下所述。

 

一、抽象数据类型

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'')) (2SELECT 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是怎么比较的.

映射方法具有效率方面的优势,因为它把每个对象与单个标量值联系在一起;排序方法有灵活方面的优势,它可以在两个对象之间进行任意复杂的比较.排序方法比映射方法的速度慢.

 

 

实例 2:

(1)定义对象类型:TYPE sales_country_t

CREATE TYPE sales_country_t AS OBJECT (

  YEAR              VARCHAR2 (4),

  country           CHAR (2),

  sum_amount_sold   NUMBER

);

 

(2)定义表类型:TYPE SUM_SALES_COUNTRY_T_TAB

CREATE TYPE sum_sales_country_t_tab AS TABLE OF sales_country_t;

 

(3)定义对象类型:TYPE sales_gender_t

CREATE TYPE sales_gender_t AS OBJECT (

  YEAR              VARCHAR2 (4),

  country_id        CHAR (2),

  cust_gender       CHAR (1),

  sum_amount_sold   NUMBER

);

 

(4)定义表类型:TYPE SUM_SALES_GENDER_T_TAB

CREATE TYPE sum_sales_gender_t_tab AS TABLE OF sales_gender_t;

 

 

(5) 也可以使用基本类型定义  表类型比如:

create or replace type test_tab_type as table of varchar2(4000); /

varchar2(4000) 是一个资本类型,这样相当于定义的表中只有一个字段varchar2(4000)

 

用法:

TYPE sales_country_t_rec IS RECORD (
      YEAR              VARCHAR (4), country CHAR (2), sum_amount_sold NUMBER ); v_sales_country_t_rec sales_country_t_rec;

引用:

v_sales_country_t_rec.year := 'ssss'; v_sales_country_t_rec.country := 'a'; v_sales_country_t_rec.sum_amount_sold := 2 ;

 

----------------------------------------------------------

 

1 首先创建一个数据类型

create type t_air  as object(id int ,name varchar(20));

2 创建表

create table aaa(

       id int ,person t_air);

3 插入数据

insert into aaa values(1,t_air(1,'23sdf'));

4 查询classPlace

select a.id ,a.persion.id,a.person.name from aaa a;

 

t_air(1,'23sdf') 使用这个方式创建一个自定义类型t_air的对象.

 

------------------------------------------------------------

三:下面简单的枚举下常用的几种自定义类型。

 

1、子类型。
这种类型最简单,类似类型的一个别名,主要是为了对常用的一些类型简单化,它基于原始的某个类型。如:
有些应用会经常用到一些货币类型:number(16,2)。如果在全局范围各自定义这种类型,一旦需要修改该类型的精度,则需要一个个地修改。
那如何实现定义的全局化呢?于是就引出了子类型:
subtype cc_num is number(16,2);
这样就很方便地解决了上述的麻烦。

 

 

 

整理:

http://blog.csdn.net/qfs_v/article/details/2446941

http://blog.csdn.net/feimashenhua/article/details/7177948

http://blog.itpub.net/12932950/viewspace-662514

http://psoug.org/reference/type.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值