定義對象表
對象表就像普通的表一樣,只是存儲的是對象類型,該表的每一個字段與對象的一個屬性相對應。對象表的每一條記錄存儲一個對象類型的實例。語法如下:
CREATE TALE table_name OF object_type;
對象表基於的是系統定義的構造函數,而不是用戶定義的構造函數,所以在向對象表插入數據時,必須要在構造函數中提供匹配的所有的屬性值。
創建的對象表一旦引用了特定的對象類型,就不能使用DROP TYPE刪除對象類型。
插入對象表
以上一篇文章中創建的employee_personobj
爲例,我們先來創建一個對象表:
CREATE TABLE emp_obj_table OF employee_personobj;
然後插入數據:
INSERT INTO emp_obj_table VALUES('張小五','F',
TO_DATE('1983-01-01','YYYY-MM-DD'),
'中信',7981,5000,'Programmer');
也可以這樣插入數據:
DECLARE
o_emp employee_personobj; --定義員工對象類型的變量
BEGIN
--使用構造函數實例化員工對象
o_emp:=employee_personobj('張小五','F',
TO_DATE('1983-01-01','YYYY-MM-DD'),
'中信',7981,5000,'Programmer');
INSERT INTO emp_obj_table VALUES(o_emp); --插入到對象表中
END;
檢索對象表
除了使用跟傳統的關係表檢索數據一樣的方法外,對象表還有VALUE和REF函數這兩種檢索方法。
VALUE函數
在查詢語句中使用VALUE函數將返回存儲在對象表中的對象實例。
比如查詢單行:
DECLARE
o_emp employee_personobj; --定義一個對象類型的變量
BEGIN
--使用SELECT INTO語句將VALUE函數返回的對象實例插入到對象類型的變量
SELECT VALUE(e) INTO o_emp FROM emp_obj_table e WHERE e.person_name='張小五';
--輸出對象類型的屬性值
DBMS_OUTPUT.put_line(o_emp.person_name||'的職位是:'||o_emp.job);
END;
查詢多行:
DECLARE
o_emp employee_personobj; --定義對象類型的變量
CURSOR all_emp
IS
SELECT VALUE (e) AS emp
FROM emp_obj_table e; --定義一個遊標,用來查詢多行數據
BEGIN
FOR each_emp IN all_emp --使用遊標FOR循環檢索遊標數據
LOOP
o_emp := each_emp.emp; --獲取遊標查詢的對象實例
--輸出對象實例信息
DBMS_OUTPUT.put_line (o_emp.person_name || ' 的職位是:' || o_emp.job);
END LOOP;
END;
REF函數
REF和VALUE的區別在於REF返回的是指向對象實際位置的一個指針,而VALUE是把對象副本從一個子程序傳遞到另一個子程序。
看代碼,我們先來使用REF創建引用關係:
CREATE TYPE address AS OBJECT ( --創建地址類型
street VARCHAR2 (35),
city VARCHAR2 (15),
state CHAR (2),
zip_code INTEGER
);
CREATE TABLE addresses OF address; --創建地址對象表
CREATE TYPE person AS OBJECT ( --創建人員對象類型
person_name VARCHAR2 (15),
birthday DATE,
home_address REF address, --使用REF關鍵字,指定屬性爲指向另一個對象表的對象
phone_number VARCHAR2 (15)
);
CREATE TABLE persons OF person; --創建人員對象表
然後向addresses對象表中插入數據:
--插入地址
INSERT INTO addresses
VALUES (address ('玉蘭', '深圳', 'GD', '52334'));
INSERT INTO addresses
VALUES (address ('黃甫', '廣州', 'GD', '52300'));
接下來向persons對象表插入數據,我們將使用 REF函數,通過REF函數返回的對addressed表中特定對象的引用,插入到persons表中:
--插入一個人員,注意這裏的home_address部分是如何插入一個ref address的。
INSERT INTO persons
VALUES (person ('王小五',
TO_DATE ('1983-01-01', 'YYYY-MM-DD'),
(SELECT REF (a)
FROM addresses a
WHERE street = '玉蘭'),
'16899188'
));
也可以這樣插入:
--也可以用下面的過程來插入一個人員記錄
DECLARE
addref REF address;
BEGIN
SELECT REF (a)
INTO addref
FROM addresses a
WHERE street = '玉蘭'; --使用SELECT INTO查詢一個引用對象
--使用INSERT語句向persons表中插入引用對象
INSERT INTO persons
VALUES (person ('五大狼',
TO_DATE ('1983-01-01', 'yyyy-mm-dd'),
addref,
'16899188'
));
END;
當對象表中包含引用類型時,如果直接使用SELECT語句進行查詢,引用類型的列將會是一串數字碼,而且引用類型的對象無法直接訪問其屬性。需要使用DEREF函數,纔可以查詢到引用類型所指向的地址類型的值,如:
SELECT person_name, DEREF (home_address) FROM persons;
更新對象表
可以像更新普通表一樣更新對象表:
UPDATE emp_obj_table empobj
SET empobj.gender = 'M'
WHERE empobj.person_name = '張小五';
也可以直接更新對象表中的一個對象實例:
UPDATE emp_obj_table empobj
SET empobj=employee_personobj('李小七','F',
TO_DATE('1983-01-01','YYYY-MM-DD'),
'衆泰',7981,7000,'Testing')
WHERE person_name='張小五';
還可以在WHERE條件中使用REF函數來獲取對象的標識符(對象標識符是對象表中爲了唯一標識一條記錄而定義的一串數字值),來更新數據:
DECLARE
emp_ref REF employee_personobj; --定義引用對象類型
BEGIN
SELECT REF(e1)
INTO emp_ref
FROM emp_obj_table e1
WHERE person_name = '劉小豔'; --從對象表中獲取對劉小豔的對象引用
UPDATE emp_obj_table emp_obj
SET emp_obj =employee_personobj('何小鳳',
'F',TO_DATE ('1985-08-01', 'YYYY-MM-DD'),
'本甜',7981, 7000, 'developer')
WHERE REF (emp_obj) = emp_ref; --使用UPDATE語句更新emp_obj_table表中劉小豔的記錄
END;
如果對象表的屬性列表中包含了引用類型,而我們需要修改其列所引用的數據,就必須修改相應的 行對象。例如在persons表中,hone_address
字段是一個指向address對象類型的引用,因此如果要UPDATE這個包含引用類型的表,可以這麼做:
DECLARE
addr address;
BEGIN
SELECT DEREF(home_address) INTO addr FROM persons WHERE person_name='王小五';
addr.street:='五一';
UPDATE address SET street=addr.street WHERE zip_code='523330';
END;
刪除對象表
如:
DELETE FROM emp_obj_table WHERE person_name='張小五';
也可以這樣:
DECLARE
emp_ref REF employee_personobj; --定義引用對象類型
BEGIN
SELECT REF(e1)
INTO emp_ref
FROM emp_obj_table e1
WHERE person_name = '劉小豔'; --從對象表中獲取對劉小豔的對象引用
DELETE FROM emp_obj_table emp_obj
WHERE REF (emp_obj) = emp_ref; --使用DELETE語句刪除emp_obj_table表中劉小豔的記錄
END;
創建對象列
除了將整個對象作爲表中的列來存儲的對象表之外,還可以爲關係對中的某一列的屬性指定爲對象類型,這種表稱爲帶對象列的關係表。
這個比較簡單,這裏就不舉例。
使用對象視圖
對象視圖可以讓我們使用面向對象的特性來操作關係型數據結構,如果想將已存在的關係型的數據更改爲使用OOP(面向對象)的操作方式,使用對象視圖非常有用。爲了創建一個對象視圖,必須首先創建一個與底層數據表的列具有相匹配屬性的對象類型。
舉個例子,要以對象的方式操作emp表,可以先基於emp表的表列定義一個對象類型,下面我們來定義個emp_tbl_obj
,用來匹配對emp表的操作:
--定義與關係表emp相匹配列的對象類型
CREATE OR REPLACE TYPE emp_tbl_obj AS OBJECT (
empno NUMBER (6),
ename VARCHAR2(10),
job VARCHAR2(18),
mgr NUMBER(4),
hiredate DATE,
sal NUMBER(7,2),
comm NUMBER(7,2),
deptno NUMBER(2),
MEMBER FUNCTION get_emp_info
RETURN VARCHAR2
)
INSTANTIABLE NOT FINAL;
/
--定義對象類型體
CREATE OR REPLACE TYPE BODY emp_tbl_obj AS
MEMBER FUNCTION get_emp_info RETURN VARCHAR2 IS
BEGIN
--在對象類型體中可以直接訪問在父對象中定義的屬性
RETURN '員工編號:'||SELF.empno||' 員工名稱:'||SELF.ename||' 職位:'||SELF.job;
END;
END;
/
接下來就可以創建一個基於該對象類型的視圖。在創建對象視圖時,必須要確定要使用的OID(對象標識符)。對象標識符是用來唯一標識一行對象的一個字符串,通過OID可以保證對對象實例引用的唯一性。OID僅在對象表和對象視圖上被創建,一旦一個OID被賦給了一個對象,那麼將永遠屬於那個對象。通常情況下,Oracle會自動產生OID值,不需要手工產生,但在定義對象視圖時,可以覆蓋系統產生OID的機制,更改爲使用對象表的額主鍵來替代。
下面來創建基於emp_tbl_obj
的對象類型的emp表的對象視圖:
--創建emp_view對象視圖
CREATE VIEW emp_view
OF emp_tbl_obj
WITH OBJECT IDENTIFIER (empno)
AS
SELECT e.empno, e.ename, e.job, e.mgr, e.hiredate, e.sal, e.comm, e.deptno
FROM emp e;
在創建了這個對象視圖以後,就可以用前面介紹的對象操作語法來操作對象了:
DECLARE
o_emp emp_tbl_obj; --定義對象類型的變量
BEGIN
--查詢對象類型
SELECT VALUE(e) INTO o_emp FROM emp_view e WHERE empno=7369;
--輸出對象類型的屬性
DBMS_OUTPUT.put_line('員工'||o_emp.ename||' 的薪資爲:'||o_emp.sal);
DBMS_OUTPUT.put_line(o_emp.get_emp_info); --調用對象類型的成員方法
END;