Oracle 9i+完整支援物件導向特性,實現關聯與物件模型無縫互通。本文系統整理五大核心概念、完整DDL/DML語法、進階特性(繼承、實例化控制、比較方法、REF/OID機制),附豐富範例碼。
CREATE [OR REPLACE] TYPE type_name
[AS | IS] OBJECT | UNDER super_type
{
attribute_name datatype [, ...] -- 成員屬性
[{MAP | ORDER} MEMBER function_name] -- 比較方法
[{FINAL | NOT FINAL} MEMBER function_name] -- 可否覆寫
[{INSTANTIABLE | NOT INSTANTIABLE} MEMBER function_name] -- 可否實例化
[{MEMBER | STATIC} function_name] -- 靜態/實例方法
}
[{FINAL | NOT FINAL}] -- 類型可否被繼承
[{INSTANTIABLE | NOT INSTANTIABLE}] -- 類型可否實例化
/
CREATE [OR REPLACE] TYPE BODY type_name AS
[{MAP | ORDER} MEMBER function_body]
[{MEMBER | STATIC} function_name]
END;
/
-- 範例
CREATE OR REPLACE TYPE person AS OBJECT(
first_name VARCHAR2(100),
last_name VARCHAR2(100)
);
/
-- 建構函數:需傳入所有屬性(含NULL)
DECLARE
l_person person := person('Donny','Chen');
BEGIN
DBMS_OUTPUT.PUT_LINE(l_person.first_name);
END;
/
不可用:LONG/LONG RAW、NCHAR/NCLOB/NVARCHAR2、ROWID/UROWID、PL/SQL特有%TYPE/%ROWTYPE。
CREATE TABLE person_table (
name person,
age NUMBER
);
INSERT INTO person_table VALUES (person('Donny','Chen'), 30);
SELECT p.name.first_name FROM person_table p; -- 需表別名避免名稱解析錯誤
CREATE OR REPLACE TYPE employee AS OBJECT(
name person, -- 內嵌person型別
empno NUMBER,
hiredate DATE
);
INVALIDATE:依賴物件標記失效,需手動ALTER TABLE ... UPGRADE [INCLUDING|NOT INCLUDING] DATACASCADE:資料庫自動驗證依賴表,NOT INCLUDING TABLE DATA保留舊資料結構ALTER TYPE person ADD ATTRIBUTE ssn VARCHAR2(11) INVALIDATE;
ALTER TABLE person_table UPGRADE INCLUDING DATA; -- ssn置NULL
ALTER TYPE person ADD ATTRIBUTE dob DATE CASCADE NOT INCLUDING TABLE DATA;
STATIC:型別層級呼叫,無SELFMEMBER:實例層級,可存取SELFCONSTRUCTOR:建構函數(隱含)-- MAP:回傳可排序標量(如empno)
MAP MEMBER FUNCTION convert RETURN NUMBER IS BEGIN RETURN SELF.empno; END;
-- ORDER:回傳-1/0/1,自訂比較邏輯
ORDER MEMBER FUNCTION match(p_employee employee) RETURN INTEGER IS
BEGIN
IF SELF.empno > p_employee.empno THEN RETURN 1;
ELSIF SELF.empno < p_employee.empno THEN RETURN -1;
ELSE RETURN 0; END IF;
END;
FINAL(不可繼承),方法預設NOT FINAL(可覆寫)NOT INSTANTIABLE ≈ 抽象類,需子類實作CREATE TYPE employee_type AS OBJECT(employee_id NUMBER, first_name VARCHAR2(30), last_name VARCHAR2(30));
CREATE TYPE employee_list_type AS VARRAY(50) OF employee_type; -- 固定上限50
CREATE TABLE departments (
department_id NUMBER,
department_name VARCHAR2(30),
manager employee_type,
employees employee_list_type
);
INSERT INTO departments VALUES (10, 'HR', employee_type(1,'Donny','Chen'),
employee_list_type(employee_type(2,'Hua','Li'), employee_type(3,'Wu','Wang')));
-- VARRAY儲存於同一表列,有序、有上限
CREATE TYPE order_item_type AS OBJECT(line_item_id NUMBER(3), product_id NUMBER(6), unit_price NUMBER(8,2), quantity NUMBER(4));
CREATE TYPE order_item_list_type AS TABLE OF order_item_type; -- 無上限
CREATE TABLE orders (
order_id NUMBER(12),
order_date DATE,
customer_id NUMBER(6),
order_items order_item_list_type
) NESTED TABLE order_items STORE AS order_items_tab; -- 獨立儲存表
-- 無數量限制,適合大量子項
CREATE TYPE address AS OBJECT(id NUMBER, street VARCHAR2(100), state VARCHAR2(2), zipcode VARCHAR2(11));
CREATE TABLE address_table OF address; -- 每列為一物件實例
INSERT INTO address_table VALUES (1, 'Oracle way', 'CA', '90001');
INSERT INTO address_table VALUES (address(2, 'Oracle way2', 'CA', '90011'));
SELECT VALUE(a) FROM address_table a; -- 回傳完整物件實例
CREATE TABLE employee_location (
empno NUMBER,
loc_ref REF address SCOPE IS address_table -- 限制指向address_table
);
INSERT INTO employee_location SELECT 12345, REF(a) FROM address_table a WHERE id=1;
-- REF() 建立指標,DEREF() 解引用,IS DANGLING 檢測懸空指標
CREATE TABLE item (itemcode VARCHAR2(10), item_on_hand NUMBER(10), item_sold NUMBER(10));
CREATE TYPE item_type AS OBJECT(itemcode VARCHAR2(10), item_on_hand NUMBER(10), item_sold NUMBER(10));
CREATE VIEW item_view OF item_type
WITH OBJECT OID (itemcode) -- 明確指定OID來源
AS SELECT * FROM item;
-- 透過視圖操作物件:INSERT INTO item_view VALUES (item_type('i102',15,50));
主表itemfile、從表order_detail,透過MAKE_REF建立物件參考關係。
物件關聯特性讓Oracle兼具關聯完整性與物件導向建模能力,適用於複雜領域模型、地理空間、多媒體等場景。