DM 類資料型別
類型別
DM7透過類型別在DMSQL程式中實現物件導向程式設計的支援。類將結構化的資料及對其進行操作的過程或函式封裝在一起。允許使用者根據現實世界的物件建模,而不必再將其抽象成關係資料。
DM7的類型別分為普通類型別和JAVA CLASS型別。DM文件中的示例除了特別宣告使用的是JAVA CLASS型別,要不然使用的都是普通類型別。
普通CLASS型別
DM7的類的定義分為類頭和類體兩部分,類頭完成類的宣告;類體完成類的實現。類中可以包括以下內容:
1. 型別定義
在類中可以定義遊標、異常、記錄型別、陣列型別、以及記憶體索引表等資料型別,在類的宣告及實現中可以使用這些資料型別;類的宣告中不能宣告遊標和異常,但是實現中可以定義和使用。
2. 屬性
類中的成員變數,資料型別可以是標準的資料型別,可以是在類中自定義的特殊資料型別。
3. 成員方法
類中的函式或過程,在類頭中進行宣告;其實現在類體中完成;
成員方法及後文的建構函式包含一個隱含引數,即自身物件,在方法實現中可以透過this或self來訪問自身物件,self等價於this。如果不存在重名問題,也可以直接使用物件的屬性和方法。this和self只能在包或物件指令碼中呼叫。
4. 建構函式
建構函式是類內定義及實現的一種特殊的函式,這類函式用於例項化類的物件,建構函式滿足以下條件:
1) 函式名和類名相同;
2) 函式返回值型別為自身類。
建構函式存在以下的約束:
1) 系統為每個類提供兩個預設的建構函式,分別為0參的建構函式和全參的建構函式;
2) 0參建構函式的引數個數為0,例項的物件內所有的屬性初始化值為NULL;
3) 全參建構函式的引數個數及型別和類內屬性的個數及屬性相同,按照屬性的順序依次讀取引數的值並給屬性賦值;
4) 使用者可以自定義建構函式,一個類可以有多個建構函式,但每個建構函式的引數個數必須不同;
5) 如果使用者自定義了0個引數、或引數個數同屬性個數相同的建構函式,則會覆蓋相應的預設建構函式。
下面從類的宣告、類的實現、類的刪除、類體的刪除和類的使用幾部分來詳細介紹類型別的實現過程。
類的宣告在類頭中完成。類頭定義透過CREATE CLASS語句來完成,其語法為:
語法格式
CREATE [OR REPLACE] CLASS [< 模式名>.]< 類名> [WITH ENCRYPTION] [UNDER [< 模式名>.]< 父類名>] [[NOT] FINAL] [[NOT]
INSTANTIABLE] [AUTHID DEFINER | AUTHID CURRENT_USER] AS|IS < 類內宣告列表> END [類名]
< 類內宣告列表> ::= < 類內宣告>;{< 類內宣告>;}
< 類內宣告> ::= < 變數定義>|< 過程定義>|< 函式定義>|< 型別聲名>
< 變數定義> ::= < 變數名列表> < 資料型別> [預設值定義]
< 過程定義> ::= [< 方法繼承屬性>][STATIC|MEMBER] PROCEDURE < 過程名> < 引數列表>
< 函式定義> ::= [< 方法繼承屬性>] [MAP] [STATIC|MEMBER] FUNCTION < 函式名>< 引數列表> RETURN < 返回值資料型別>[DETERMINISTIC]
[PIPELINED]
< 方法繼承屬性> ::= < 過載屬性> | | < 過載屬性>
< 過載屬性> ::= [NOT] OVERRDING
::= FINAL | NOT FINAL | INSTANTIABLE | NOT INSTANTIABLE
< 型別聲名> ::= TYPE < 型別名稱> IS < 資料型別>
使用說明
1.類中元素可以以任意順序出現,其中的物件必須在引用之前被宣告;
2.過程和函式的宣告都是前向宣告,類宣告中不包括任何實現程式碼;
3.支援物件靜態方法宣告與呼叫。可以在PROCEDURE/FUNCTION關鍵字前新增static保留字,以此指明方法為靜態方法。靜態方法只能以物件名為字首呼叫,而不能在物件例項中呼叫;
4.支援物件成員方法宣告與呼叫。可以在PROCEDURE/FUNCTION關鍵字前新增MEMBER以指明方法為成員方法。MEMBER與STATIC不能同時使用,非STATIC型別的非建構函式方法預設為成員方法。MAP表示將物件型別的例項對映為標量數值,只能用於成員型別的FUNCTION;
5.關於類繼承,有以下使用限制:
1) 類定義預設為FINAL,表示該物件型別不能被繼承,定義父類時必須指定NOT FINAL選項;
2) 定義子類時必須指定UNDER選項;
3) NOT INSTANTIABLE物件不能為FINAL;
4) NOT INSTANTIABLE物件不能例項化,但是可以用其子類賦值;
5) 物件例項化時,必須對父類和子類的成員變數都賦值,且從父類到子類逐個賦值;
6) 不支援物件的迴圈繼承;
7) 不支援物件的多繼承,即一個類有多個父類;
6) 不支援物件的迴圈繼承;
7) 不支援物件的多繼承,即一個類有多個父類;
8) 不支援父類和子類包含同名變數;
9) 父類和子類可以同名同參,此時子類必須指定OVERRIDING;
10) 方法預設為NOT OVERRIDING,OVERRIDING不能與static一起使用;
11) 父類和子類支援同名不同參(引數個數不同、引數個數相同但型別不同)的方法;
12) 同名且引數個數相同但型別不同時,根據引數型別選擇使用的方法;
13) 方法預設為INSTANTIABLE,如果宣告為NOT INSTANTIABLE,則不能與FINAL、STATIC一起使用;
14) 如果父類有多個NOT INSTANTIABLE方法,子類可以只部分重寫,但此時子類必須定義為NOT FINAL NOT INSTANTIABLE;
15) NOT INSTANTIABLE方法不能具有主體;
16) 方法預設為NOT FINAL,如果宣告為FINAL,則不能被子類重寫;
17) 子類可以賦值給父類;
18) 如果父類對應的例項是子類或者子類的孩子,則該父類可以賦值給子類;
19) 可以用INSTANTIABLE子類對NOT INSTANTIABLE父類進行賦值;
20) 子類例項賦值給父類後,呼叫時使用的是父類方法而不是子類方法;
21) 支援使用as語句轉換為父類。
所需許可權
1、使用該語句的使用者必須是DBA或具有CREATE CLASS資料庫許可權的使用者;
2、可以用關鍵字AUTHID DEFINER |AUTHID CURRENT_USER指定類的呼叫者許可權,若為DEFINER,則採用類定義者許可權,若為CURRENT_USER則為當前使用者許可權,預設為類定義者許可權。
類的實現透過類體完成。類體的定義透過CREATE CLASS BODY語句來完成,其語法為:
語法格式
CREATE [OR REPLACE] CLASS BODY [< 模式名>.]< 類名> [WITH ENCRYPTION] AS|IS < 類體部分> END [類名]
< 類體部分> ::= < 過程/函式列表> [< 初始化程式碼>]
< 過程/函式列表> ::= < 過程實現|函式實現>{,< 過程實現|函式實現> }
< 過程實現> ::= [< 方法繼承屬性>][STATIC|MEMBER]PROCEDURE < 過程名> < 引數列表> AS|IS BEGIN < 實現體> END [過程名]
< 函式實現> ::= [< 方法繼承屬性>][MAP] [STATIC|MEMBER]FUNCTION < 函式名>< 引數列表> RETURN < 返回值資料型別>[DETERMINISTIC] [PIPELINED] AS|IS BEGIN < 實現體> END [函式名]
< 方法繼承屬性> ::= < 過載屬性> | | < 過載屬性>
< 過載屬性> ::= [NOT] OVERRDING
::= FINAL | NOT FINAL | INSTANTIABLE | NOT INSTANTIABLE
< 初始化程式碼> ::= [[< 說明部分>]BEGIN< 執行部分>[< 異常處理部分>]]
< 說明部分> ::=[DECLARE]< 說明定義>{< 說明定義>}
< 說明定義>::=< 變數說明>|< 異常變數說明>|< 遊標定義>|< 子過程定義>|< 子函式定義>
< 變數說明>::=< 變數名>{,< 變數名>}< 變數型別>[DEFAULT|ASSIGN|:=< 表示式>];
< 變數型別>::=|< [模式名.]表名.列名%TYPE>|< [模式名.]表名%ROWTYPE>|< 記錄型別>
< 記錄型別>::= RECORD(< 變數名> {,< 變數名> })
< 異常變數說明>::=< 異常變數名>EXCEPTION[FOR< 錯誤號>]
< 異常處理語句>::= WHEN < 異常名> THEN < SQL過程語句序列>
使用說明
1. 類宣告中定義的物件對於類體而言都是可見的,不需要宣告就可以直接引用。這些物件包括變數、遊標、異常定義和型別定義;
2. 類體中的過程、函式定義必須和類宣告中的宣告完全相同。包括過程的名字、引數定義列表的引數名和資料型別定義;
3. 類中可以有重名的成員方法,要求其引數定義列表各不相同。系統會根據使用者的呼叫情況進行過載(OVERLOAD);
4. 宣告類與實現類時,對於確定性函式的指定邏輯與包內函式相同。目前不支援類的確定性函式在函式索引中使用。
所需許可權
使用該語句的使用者必須是DBA或該類物件的擁有者且具有CREATE CLASS資料庫許可權的使用者。
完整的類頭、類體的建立如下所示:
----類頭建立
SQL> create or replace class mycls 2 as 3 type rec_type is record (c1 int, c2 int); --型別宣告 4 id int; --成員變數 5 r rec_type; --成員變數 6 function f1(a int, b int) return rec_type; --成員函式 7 function mycls(id int , r_c1 int, r_c2 int) return mycls; 8 --使用者自定義建構函式 9 end; 10 / executed successfully used time: 14.032(ms). Execute id is 106.
----類體建立
SQL> create or replace class body mycls 2 as 3 function f1(a int, b int) return rec_type 4 as 5 begin 6 r.c1 = a; 7 r.c2 = b; 8 return r; 9 end; 10 function mycls(id int, r_c1 int, r_c2 int) return mycls 11 as 12 begin 13 this.id = id; --可以使用this.來訪問自身的成員 14 r.c1 = r_c1; --this也可以省略 15 r.c2 = r_c2; 16 return this; --使用return this 返回本物件 17 end; 18 end; 19 / executed successfully used time: 61.783(ms). Execute id is 107.
重編譯類
重新對類進行編譯,如果重新編譯失敗,則將類置為禁止狀態。
重編功能主要用於檢驗類的正確性。
語法格式
ALTER CLASS [< 模式名>.]< 類名> COMPILE [DEBUG];
引數
1.< 模式名> 指明被重編譯的類所屬的模式;
2.< 類名> 指明被重編譯的類的名字;
3.[DEBUG] 可忽略。
所需許可權
執行該操作的使用者必須是類的建立者,或者具有DBA許可權。
舉例說明
例如重新編譯類
SQL> ALTER CLASS mycls COMPILE; executed successfully used time: 8.867(ms). Execute id is 108.
刪除類
類的刪除分為兩種方式:一是類頭的刪除,刪除類頭則會順帶將類體一起刪除;另外一種是類體的刪除,這種方式只能刪除類體,類頭依然
存在。
刪除類頭
類的刪除透過DROP CLASS完成,即類頭的刪除。刪除類頭的同時會一併刪除類體。
語法格式
DROP CLASS [< 模式名>.]< 類名>[RESTRICT | CASCADE]; 使用說明
1.如果被刪除的類不屬於當前模式,必須在語句中指明模式名;
2.如果一個類的宣告被刪除,那麼對應的類體被自動刪除。
所需許可權
執行該操作的使用者必須是該類的擁有者,或者具有DBA許可權。
刪除類體
從資料庫中刪除一個類的實現主體物件。
語法格式
DROP CLASS BODY [< 模式名>.]< 類名>[RESTRICT | CASCADE]; 使用說明
如果被刪除的類不屬於當前模式,必須在語句中指明模式名。
許可權
執行該操作的使用者必須是該類的擁有者,或者具有DBA許可權。
類的使用
類型別同普通的資料型別一樣,可以作為表中列的資料型別,DMSQL程式語句塊中變數的資料型別或過程及函式引數的資料型別。
具體使用規則
1.作為表中列型別或其他類成員變數屬性的類不能被修改,刪除時需要指定CASCADE級聯刪除類中定義的資料型別,其名稱只在類的宣告及實現中有效。如果類內的函式的引數或返回值是類內的資料型別,或是進行類內成員變數的複製,需要在DMSQL程式中定義一個結構與之相同的型別。
根據類使用方式的不同,物件可分為變數物件及列物件。變數物件指的是在DMSQL程式語句塊中宣告的類型別的變數;列物件指的是在表中類型別的列。變數物件可以修改其屬性的值而列物件不能。
2.變數物件的例項化
類的例項化透過NEW 表示式呼叫建構函式完成。
3.變數物件的引用
透過‘=’進行的類型別變數之間的賦值所進行的是物件的引用,並沒有複製一個新的物件。
4.變數物件屬性訪問
可以透過如下方式進行屬性的訪問。
< 物件名>.< 屬性名>
5.變數物件成員方法呼叫
成員方法的呼叫透過以下方式呼叫:
< 物件名>.< 成員方法名>(< 引數>{,< 引數>})
如果函式內修改了物件內屬性的值,則該修改生效。
6.列物件的插入
列物件的建立是透過INSERT語句向表中插入資料完成,插入語句中的值是變數物件,插入後儲存在表中的資料即為列物件。
7.列物件的複製
儲存在表中的物件不允許對物件中成員變數的修改,透過into查詢或’=’進行的列到變數的賦值所進行的是物件的賦值,生成了一個與列物件資料一樣的副本,在該副本上進行的修改不會影響表中列物件的值。
8.列物件的屬性訪問
透過如下方式進行屬性的訪問:
< 列名>.< 屬性名>
9.列物件的方法呼叫
< 列名>.< 成員方法名>(< 引數>{,< 引數>})
列物件方法呼叫過程中對型別內屬性的修改,都是在列物件的副本上進行的,不會影響列物件的值。
應用例項
1. 變數物件的應用例項
SQL> declare 2 type ex_rec_t is record (a int, b int); --使用一個同結構的型別代替類定義的型別 3 rec ex_rec_t; 4 o1 mycls; 5 o2 mycls; 6 begin 7 o1 = new mycls(1,2,3); 8 o2 = o1; --物件引用 9 rec = o2.r; --變數物件的成員變數訪問 10 print rec.a; print rec.b; 11 rec = o1.f1(4,5); --成員函式呼叫 12 print rec.a; print rec.b; 13 print o1.id; --成員變數訪問 14 end; 15 / 2 3 4 5 1 DMSQL executed successfully used time: 3.129(ms). Execute id is 109.
2. 列物件的應用例項
表的建立。
SQL> create table tt1(c1 int, c2 mycls); executed successfully used time: 28.302(ms). Execute id is 112.
列物件的建立--插入資料。
SQL> insert into tt1 values(1, mycls(1,2,3)); affect rows 1 used time: 22.639(ms). Execute id is 113. SQL> commit; executed successfully used time: 17.285(ms). Execute id is 114.
列物件的複製及訪問。
SQL> declare 2 o mycls; 3 id int; 4 begin 5 select top 1 c2 into o from tt1; --列物件的複製 6 select top 1 c2.id into id from tt1; --列物件成員的訪問 7 end; 8 / DMSQL executed successfully used time: 33.518(ms). Execute id is 115.
3. 類繼承的應用例項
SQL> CREATE OR REPLACE CLASS cls01 NOT FINAL IS 2 name VARCHAR2(10); 3 MEMBER FUNCTION get_info RETURN VARCHAR2; 4 END; 5 / executed successfully used time: 22.220(ms). Execute id is 116. SQL> CREATE OR REPLACE CLASS cls02 UNDER cls01 IS 2 ID INT; 3 OVERRIDING MEMBER FUNCTION get_info RETURN VARCHAR2; 4 END; 5 / executed successfully used time: 14.072(ms). Execute id is 117.
JAVA CLASS型別
JAVA類的定義類似JAVA語言語法,類中可定義。
JAVA類中可以包括以下內容:
1. 型別定義
在類中可以定義遊標、異常,可以宣告記錄型別、陣列型別、結構體型別以及記憶體索引表等資料型別變數。
2. 屬性
類中的成員變數,資料型別可以是標準的資料型別,可以是在類外自定義的特殊資料型別。
3. 成員方法
JAVA類中的成員方法及後文的建構函式包含一個隱含引數,即自身物件,在方法實現中可以透過this或self來訪問自身物件,self等價於this。如果不存在重名問題,也可以直接使用物件的屬性和方法。
4. 建構函式
建構函式是類內定義及實現的一種特殊的函式,這類函式用於例項化類的物件,建構函式滿足以下條件:
1) 函式名和類名相同;
2) 函式沒有返回值型別。
建構函式存在以下的約束:
1) 系統為每個類提供兩個預設的建構函式,分別為0參的建構函式和全參的建構函式;
2) 0參建構函式的引數個數為0,例項的物件內所有的屬性初始化值為NULL;
3) 全參建構函式的引數個數及型別和類內屬性的個數及屬性相同,按照屬性的順序依次讀取引數的值並給屬性賦值;
4) 使用者可以自定義建構函式,一個類可以有多個建構函式,但每個建構函式的引數個數必須不同;
5) 如果使用者自定義了0個引數、或引數個數同屬性個數相同的建構函式,則會覆蓋相應的預設建構函式。
定義JAVA類
定義透過CREATE JAVA CLASS語句來完成,其語法為:
語法格式
CREATE [OR REPLACE] JAVA [PUBLIC] [ABSTRACT] [FINAL] CLASS < 類名> [EXTENDS [< 模式名>.]< 父類名>] {< 類內定義部分> }
< 類內定義部分> ::= < 類內定義列表>
< 類內定義列表> ::= < 類內定義>;{< 類內定義>;}
< 類內定義> ::= [PUBLIC|PRIVATE] < 變數定義>|< 方法定義>
< 變數定義> ::= < 變數屬性> < 資料型別>< 變數名列表> [預設值定義]
< 變數屬性> ::= [STATIC]
< 方法定義> ::= [PUBLIC|PRIVATE] [< 方法繼承屬性>] [STATIC] < 返回型別> < 函式名>< 引數列表> { < 實現體> }
< 方法繼承屬性> ::= < 過載屬性> | |
::= ABSTRACT
::= FINAL
< 過載屬性> ::= OVERRIDE
使用說明
1.類中元素可以以任意順序出現,其中的物件必須在引用之前被宣告。
2.支援物件靜態方法宣告與呼叫。可以在方法前新增static保留字,以此指明方法為靜態方法。靜態方法只能以物件名為字首呼叫,而不能在物件例項中呼叫。
3.支援物件成員方法宣告與呼叫。非STATIC型別的非建構函式方法預設為成員方法。成員方法呼叫時,需要先例項化,例項化引數值預設為null。
4. 變數定義還包括遊標、異常定義。
5.方法屬性是PUBLIC,則訪問類時可以訪問,如果是PRIVATE屬性,則訪問類時不可以訪問該方法。
6.關於JAVA 類繼承,有以下使用限制:
1) JAVA CLASS定義預設可繼承,FINAL表示該類不能被繼承;
2) 定義子類時必須指定EXTENDS選項;
3) ABSTRACT物件不能為FINAL;
4) ABSTRACT物件不能例項化,但是可以用其子類賦值;
5) 子類物件例項化時,必須對父類和子類的成員變數都賦值,且從父類到子類逐個賦值;
6) 不支援物件的迴圈繼承;
7) 不支援物件的多繼承,即一個類只能有一個父類;
8) 不支援父類和子類包含同名變數;
9) 父類和子類可以同名同參,此時子類必須指定OVERRIDE;
10) 方法預設為NOT OVERRIDING,OVERRIDING不能與static一起使用;
11) 父類和子類支援同名不同參(引數個數不同、引數個數相同但型別不同)的方法;
12) 同名且引數個數相同但型別不同時,根據引數型別選擇使用的方法;
13) 方法如果宣告為ABSTRACT,則不能與FINAL、STATIC一起使用;
14) 如果父類有多個ABSTRACT方法,子類可以只部分重寫,但此時子類必須定義為ABSTRACT;
15) ABSTRACT方法不能具有主體;
16) 方法預設為可繼承,如果宣告為FINAL,則不能被子類重寫;
17) 子類可以賦值給父類;
18) 如果父類對應的例項是子類或者子類的孩子,則該父類可以賦值給子類;
19) 可以用ABSTRACT子類對非ABSTRACT父類進行賦值;
20) 子類例項賦值給父類後,呼叫時使用的是父類方法而不是子類方法;
21) 支援使用super無參方法轉換為父類引用;
22) 支援使用this()呼叫該類建構函式,super()呼叫父類建構函式;
23) 子類必須有新增成員或方法,不能完全為空。
重編譯JAVA類
重新對JAVA類進行編譯,如果重新編譯失敗,則將JAVA類置為禁止狀態。
重編功能主要用於檢驗JAVA類的正確性。
語法格式
ALTER JAVA CLASS [< 模式名>.] COMPILE [DEBUG];
引數
1.< 模式名> 指明被重編譯的JAVA類所屬的模式;
2. 指明被重編譯的JAVA類的名字;
3.[DEBUG] 可忽略。
所需許可權
執行該操作的使用者必須是JAVA類的建立者,或者具有DBA許可權。
12.2.3 刪除JAVA類
JAVA類的刪除透過DROP CLASS完成。
語法格式
DROP CLASS < 類名>[RESTRICT | CASCADE];
類的使用
下面列舉一個簡單的應用例項。在列物件上如何使用JAVA CLASS。
1.建立JAVA CLASS。
SQL> create or replace java class jcls 2 { 3 int a; 4 public static int testAdd2(int a, int b) 5 { //此處建立的是靜態STATIC方法 6 return a + b; 7 } 8 public int testAdd3(int a, int b, int c) 9 { //此處建立的是成員方法 10 return a + b +c; 11 } 12 }; 13 / executed successfully used time: 16.964(ms). Execute id is 123.
2. 在列物件中使用JAVA CLASS。
SQL> create table tt2(c1 int, c2 jcls); executed successfully used time: 9.261(ms). Execute id is 124. SQL> insert into tt2 values(jcls.testadd2(1,2),jcls(1)); //靜態方法呼叫 2 / affect rows 1 used time: 1.255(ms). Execute id is 125. SQL> insert into tt2 values(jcls().testadd3(1,2,3),jcls(2)); //成員方法呼叫之前必須例項化 2 / affect rows 1 used time: 1.023(ms). Execute id is 126.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26015009/viewspace-2681032/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- DM自定義資料型別資料型別
- js資料型別之基本資料型別和引用資料型別JS資料型別
- JS資料型別分類和判斷JS資料型別
- MySQL 資料型別分類和選擇MySQL 資料型別
- 基本資料型別及其包裝類(二)資料型別
- 基本資料型別及其包裝類(一)資料型別
- 什麼是組合資料型別?Python組合資料型別分為幾類?資料型別Python
- 資料型別: 資料型別有哪些?資料型別
- DM8 varchar型別長度型別
- 區別值型別資料和引用型別資料型別
- Java-API-基本資料型別包裝類JavaAPI資料型別
- 資料型別,型別轉換資料型別
- 資料型別資料型別
- 第10章 物件和類——物件和類(六) 抽象資料型別物件抽象資料型別
- Java 包裝類:原始資料型別與迭代器Java資料型別
- Python資料型別是什麼?七大類!Python資料型別
- JAVA中基本資料型別和引用資料型別Java資料型別
- 3. php資料型別、資料型別轉換PHP資料型別
- 基本資料型別與字串型別資料型別字串
- MySQL基礎之----資料型別篇(常用資料型別)MySql資料型別
- Java中的基本資料型別與引用資料型別Java資料型別
- 定義多維的點模板類,任意資料型別資料型別
- mysql中數值型資料有哪兩個類別?MySql
- JavaScript - 資料型別JavaScript資料型別
- Symbol資料型別Symbol資料型別
- 資料型別2資料型別
- JavaScript 資料型別JavaScript資料型別
- js資料型別JS資料型別
- TypeScript資料型別TypeScript資料型別
- Oracle 資料型別Oracle資料型別
- SQL 資料型別SQL資料型別
- NumPy 資料型別資料型別
- php資料型別PHP資料型別
- numpy資料型別資料型別
- JavaScript資料型別JavaScript資料型別
- 一、資料型別資料型別
- [Mysql]資料型別MySql資料型別
- MySQL資料型別MySql資料型別