Oracle PL/SQL高級編程(第二彈:管理對象表)

定義對象表

對象表就像普通的表一樣,只是存儲的是對象類型,該表的每一個字段與對象的一個屬性相對應。對象表的每一條記錄存儲一個對象類型的實例。語法如下:
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;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章