Oracle对象类型

PL/SQL允许定义一个对象类型,这有助于在Oracle的数据库中设计的面向对象。对象类型可以包装复合类型。

创建对象:

CREATE OR REPLACE TYPE objName AS OBJECT
(
 --定义对象类型属性  
 var1 type,
 var2 type,
 var3 type,
 ...
 -- 定义对象的成员方法,可以访问对象本身的属性
 MEMBER FUNCTION fun_name1[(参数名 数据类型[,...])] return return_type,
 MEMBER PROCEDURE proc_name1[(参数名 数据类型[,...])]

--静态方法,不能访问对象本身的属性,只能访问静态数据 
 STATIC FUNCTION fun_name2[(参数名 数据类型[,...])] return return_type,
 STATIC PROCEDURE proc_name2[(参数名 数据类型[,...])]
);

创建类型体:

CREATE OR REPLACE TYPE BODY objName AS
   -- 实现对象成员方法
   MEMBER FUNCTION fun_name1[(参数名 数据类型[,...])] 
   RETURN return_type
   AS
   BEGIN
      <function_body>
   END fun_name1;

   MEMBER proc_name1[(参数名 数据类型[,...])] 
   AS
   BEGIN
      <procedure_body>
   END proc_name1;

   STATIC FUNCTION fun_name2[(参数名 数据类型[,...])] 
   RETURN return_type
   AS
   BEGIN
      <function_body>
   END fun_name2;

   STATIC proc_name2[(参数名 数据类型[,...])] 
   AS
   BEGIN
      <procedure_body>
   END proc_name2;
END;

实例化对象:
  要使用这个对象,需要创建这个对象的实例。每个对象都有一个系统定义的构造方法,构造方法的名称是相同的对象类型。

DECLARE
   residence objName; -- 定义对象类型
BEGIN
   -- 初始化对象类型
   residence := address('103A', 'M.G.Road', 'Jaipur', 'Rajasthan','201301');
   -- 获取对象类型的属性进行显示 
   dbms_output.put_line('House No: '|| residence.house_no);
   dbms_output.put_line('Street: '|| residence.street);
   dbms_output.put_line('City: '|| residence.city);
END;
/

比较方法
比较方法被用于比较的对象。有两种方法来比较对象:

  • 映射方法:将对象实例映射为标量数值(NUMBER,DATE,VARCHAR2等),然后根据该标量类型数据可以排序对象实例。例如,一个客户对象,如果两个客户代码是相同的,可以认为是相同的一个。所以这两个对象之间的关系将取决于代码的值。
  • 顺序方法:实现一些内部逻辑比较两个对象。
  • 一个对象类型最多只能定义一个MAP/ORDER方法,并且MAP方法和ORDER方法不能同时使用。
  • MAP方法可以在多个对象实例之间进行排序,而ORDER方法只能比较两个对象实例的大小

(1)映射方法

CREATE OR REPLACE TYPE book_obj AS OBJECT (
   isbn        CHAR (10),
   title       VARCHAR2 (100),
   num_pages   NUMBER,
   MAP MEMBER FUNCTION return_isbn RETURN CHAR
);

CREATE OR REPLACE TYPE BODY book_obj
AS
  MAP MEMBER FUNCTION return_isbn RETURN CHAR AS
   BEGIN
      RETURN SELF.isbn;
   END return_isbn;
END;

--现在就可以通过isdn来比较两个对象
DECLARE
    v_book1   book := book ('72121203', 'Oracle DBA 101', 563);
    v_book2   book := book ('72122048', 'Oracle 8i: A Beginner''s Guide', 765);

 BEGIN
    IF v_book1 < v_book2 THEN
       DBMS_OUTPUT.put_line (v_book1.title || ' < ' || v_book2.title);
    ELSIF v_book1 = v_book2 THEN
       DBMS_OUTPUT.put_line (v_book1.title || ' = ' || v_book2.title);
    ELSE
       DBMS_OUTPUT.put_line (v_book1.title || ' > ' || v_book2.title);
    END IF;
 END;

(2)使用顺序的方法
现在,相同的效果可以使用顺序方法来实现。

CREATE OR REPLACE TYPE book_obj AS OBJECT (
   isbn        CHAR (10),
   title       VARCHAR2 (100),
   num_pages   NUMBER,
   ORDER MEMBER FUNCTION compare_book (p_isbn IN BOOK_OBJ) RETURN CHAR
);

CREATE OR REPLACE TYPE BODY book_obj
AS
   ORDER MEMBER FUNCTION compare_book (p_isbn IN BOOK_OBJ) RETURN NUMBER AS
   BEGIN
      IF p_isbn.isbn < SELF.isbn THEN
         RETURN 1;
      ELSIF p_isbn.isbn > SELF.isbn THEN
         RETURN -1;
      ELSE
         RETURN 0;
      END IF;
   END compare_book;
END;
 DECLARE
    v_book1   book := book ('72121203', 'Oracle DBA 101', 563);
    v_book2   book := book ('72122048', 'Oracle 8i: A Beginner''s Guide', 765);
 BEGIN
    IF v_book1 < v_book2 THEN
       DBMS_OUTPUT.put_line (v_book1.title || ' < ' || v_book2.title);
    ELSIF v_book1 = v_book2 THEN
       DBMS_OUTPUT.put_line (v_book1.title || ' = ' || v_book2.title);
    ELSE
       DBMS_OUTPUT.put_line (v_book1.title || ' > ' || v_book2.title);
    END IF;
 END;

继承PL/SQL对象
  PL/SQL允许从现有的基础对象创建对象。为了实现继承,基本对象应被声明为NOT FINAL。默认值是FINAL。

基础对象:

CREATE OR REPLACE TYPE baseObj AS OBJECT
(
  var1 type,
  var2 type,
  MEMBER FUNCTION fu_name[(参数名 数据类型[,...])] return reu_type
)NOT FINAL; --指定该类可以被继承,如果指定FINAL,表示该类无法被继承 

子类对象:

CREATE OR REPLACE TYPE subObj UNDER baseObj 
(  
   v1 type,
   v2 type,
   -- 声明重写父类方法
   OVERRIDING MEMBER FUNCTION fu_name[(参数名 数据类型[,...])] 
)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容