Oracle 8i+ 引入物件導向特性:封裝 (資料與方法結合)、繼承 (型別層次)、多型 (執行期動態綁定)。物件型別 = 類別,物件實例 = 物件。
CREATE OR REPLACE TYPE emp_obj AS OBJECT (
emp_id NUMBER,
emp_name VARCHAR2(50),
salary NUMBER,
-- Member Function (方法)
MEMBER FUNCTION get_annual_sal RETURN NUMBER,
-- Map Method (用於比較/排序)
MAP MEMBER FUNCTION get_id RETURN NUMBER
);
/
CREATE OR REPLACE TYPE BODY emp_obj AS
MEMBER FUNCTION get_annual_sal RETURN NUMBER IS
BEGIN
RETURN self.salary * 12;
END;
MAP MEMBER FUNCTION get_id RETURN NUMBER IS
BEGIN
RETURN self.emp_id;
END;
END;
/
-- PL/SQL 區塊中宣告區域變數
DECLARE
v_emp emp_obj := emp_obj(1001, 'Alice', 50000); -- 建構式初始化
BEGIN
DBMS_OUTPUT.PUT_LINE(v_emp.emp_name || ' 年薪: ' || v_emp.get_annual_sal);
END;
/
-- 或建立表儲存物件 (見下節)
CREATE TABLE departments (
dept_id NUMBER PRIMARY KEY,
dept_name VARCHAR2(100),
manager emp_obj -- 物件欄位
);
INSERT INTO departments VALUES (
10, 'IT', emp_obj(1001, 'Alice', 50000)
);
-- 查詢物件屬性
SELECT d.dept_name, d.manager.emp_name, d.manager.get_annual_sal()
FROM departments d;
CREATE TABLE employees_obj OF emp_obj (
PRIMARY KEY (emp_id)
);
INSERT INTO employees_obj VALUES (emp_obj(1001, 'Alice', 50000));
INSERT INTO employees_obj VALUES (emp_obj(1002, 'Bob', 60000));
-- 物件表查詢
SELECT VALUE(e) FROM employees_obj e WHERE e.emp_id = 1001;
-- VALUE(e) 回傳完整物件實例
| 特性 | 物件欄位 | 物件表 |
|---|---|---|
| 定義方式 | 一般表欄位型別為物件型別 | CREATE TABLE ... OF type |
| 儲存結構 | 扁平化展開為欄位 (隱含欄位) | 每屬性一欄,含系統產生 OID |
| 方法儲存 | 不儲存方法程式碼 | 不儲存方法程式碼 |
| 參考/導航 | 需 Join 父表 | 支援 REF、DEREF 導航 |
| 索引 | 可建立 Function-Based Index | 可直接對屬性建立索引 |
self.attr - other.attr)。適用複雜比較邏輯。-- 父型別
CREATE TYPE person_obj AS OBJECT (
name VARCHAR2(50),
MEMBER PROCEDURE print
) NOT FINAL; -- 允許被繼承
/
CREATE TYPE BODY person_obj AS
MEMBER PROCEDURE print IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Person: ' || name);
END;
END;
/
-- 子型別
CREATE TYPE student_obj UNDER person_obj (
student_id NUMBER,
OVERRIDING MEMBER PROCEDURE print -- 覆寫
);
/
CREATE TYPE BODY student_obj AS
OVERRIDING MEMBER PROCEDURE print IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Student: ' || name || ' ID: ' || student_id);
END;
END;
/
-- 多型展示
DECLARE
p person_obj := person_obj('John');
s student_obj := student_obj('Mary', 2024001);
BEGIN
p.print(); -- Person: John
s.print(); -- Student: Mary ID: 2024001
-- 多型指派
p := s; -- 子型別指派給父型別變數
p.print(); -- Student: Mary ID: 2024001 (動態綁定)
END;
ADDRESS_OBJ,多表共用。SDO_GEOMETRY、ORDSYS.ORDAUDIO 皆為內建物件型別。ALTER TYPE ... ADD ATTRIBUTE、REPLACE TYPE BODY 支援版本演進。Oracle 物件導向特性將資料與行為封裝於資料庫層,配合 MAP/ORDER 比較、型別繼承多型、REF 導航,能優雅處理複雜業務模型。掌握 CREATE TYPE、物件欄位 vs 物件表選型、建構式初始化,是進階 PL/SQL 開發者的必修課。