※屬性、方法
※宣告
CREATE OR REPLACE TYPE xxx_emp IS OBJECT( xxx_empno NUMBER(4), xxx_sal NUMBER(7,2), xxx_deptno NUMBER(2), MEMBER PROCEDURE update_sal(v_percent NUMBER), STATIC PROCEDURE update_sal(v_deptno NUMBER, v_percent NUMBER), MEMBER FUNCTION get_sal RETURN NUMBER, STATIC FUNCTION get_sal(v_empno NUMBER) RETURN NUMBER ) NOT FINAL;
※一定要宣告屬性,但可以沒有方法
※宣告了3個屬性和4個方法;方法又分成兩個靜態方法和兩個一般方法
※TYPE的型態不能使用%TYPE之類的語法
※MEMBER的NUMBER不能用NUMBER(2),可能括號會誤判吧
※實作
CREATE OR REPLACE TYPE BODY xxx_emp IS MEMBER PROCEDURE update_sal(v_percent NUMBER) IS BEGIN UPDATE EMP SET SAL = SAL * (1 + v_percent) WHERE EMPNO = SELF.xxx_empno; END; STATIC PROCEDURE update_sal(v_deptno NUMBER, v_percent NUMBER) IS BEGIN UPDATE EMP SET SAL = SAL * (1 + v_percent) WHERE DEPTNO = v_deptno; END; MEMBER FUNCTION get_sal RETURN NUMBER IS ooo_sal_comm NUMBER; BEGIN SELECT SAL + NVL(COMM, 0) INTO ooo_sal_comm FROM EMP WHERE EMPNO = SELF.xxx_empno; RETURN ooo_sal_comm; END; STATIC FUNCTION get_sal(v_empno NUMBER) RETURN NUMBER IS ooo_sal_comm NUMBER; BEGIN SELECT SAL + NVL(COMM, 0) INTO ooo_sal_comm FROM EMP WHERE EMPNO = v_empno; RETURN ooo_sal_comm; END; END;
※實作時,將整個方法複製過來,將TYPE改成TYPE BODY,然後Object()不要,最後變END,而且只要實作方法即可,屬性不用
※靜態的方法不能使用SELF關鍵字,相當於java的this
※最後的END不能寫END xxx_update_emp
※可以在圖中看到TYPE和TYPE BODY
※測試
DECLARE ooo_emp xxx_emp; BEGIN ooo_emp := xxx_emp(7521, 1250, 30); ooo_emp.xxx_sal := 2000; DBMS_OUTPUT.PUT_LINE(ooo_emp.xxx_sal); DBMS_OUTPUT.PUT_LINE('修改前:' || ooo_emp.get_sal()); DBMS_OUTPUT.PUT_LINE('靜態修改前:' || xxx_emp.get_sal(7499)); ooo_emp.update_sal(0.2); DBMS_OUTPUT.PUT_LINE('修改後:' || ooo_emp.get_sal()); xxx_emp.update_sal(30, 0.2); DBMS_OUTPUT.PUT_LINE('靜態修改後:' || xxx_emp.get_sal(7499)); END;
※和java一樣,要呼叫靜態方法時,要用「類別.方法」
※2000那行只有在顯示有用,並沒有真的存到資料庫
※如果要刪除類別,指令要下「DROP TYPE xxx_emp;」
※建構子
※宣告
CREATE OR REPLACE TYPE xxx_constructor IS OBJECT( xxx_empno NUMBER(4), xxx_sal NUMBER(7,2), xxx_deptno NUMBER(2), CONSTRUCTOR FUNCTION xxx_constructor(p_empno NUMBER) RETURN SELF AS RESULT, CONSTRUCTOR FUNCTION xxx_constructor(p_empno NUMBER, p_deptno NUMBER) RETURN SELF AS RESULT ) NOT FINAL;
※寫了兩個建構子,但其實還有一個是傳3個參數的,也就是宣告的3個屬性,這也是一個建構子
※沒有CONSTRUCTOR PROCEDURE這種語法
※實作
CREATE OR REPLACE TYPE BODY xxx_constructor IS CONSTRUCTOR FUNCTION xxx_constructor(p_empno NUMBER) RETURN SELF AS RESULT IS BEGIN SELF.xxx_empno := p_empno; SELECT SAL INTO SELF.xxx_sal FROM EMP WHERE EMPNO = p_empno; RETURN; END; CONSTRUCTOR FUNCTION xxx_constructor(p_empno NUMBER, p_deptno NUMBER) RETURN SELF AS RESULT IS BEGIN SELF.xxx_empno := p_empno; SELF.xxx_sal := 1500; SELF.xxx_deptno := p_deptno; RETURN; END; END;
※一定要寫RETURN,雖然編譯會過,但呼叫時,會出「ORA-06503: PL/SQL: 函數沒有傳回任何值」的錯
※測試
DECLARE ooo_cons1 xxx_constructor; ooo_cons2 xxx_constructor; ooo_cons3 xxx_constructor; BEGIN ooo_cons1 := xxx_constructor(7521, 1250, 30); ooo_cons2 := xxx_constructor(7499); ooo_cons3 := xxx_constructor(7654, 30); DBMS_OUTPUT.PUT_LINE(ooo_cons1.xxx_sal); DBMS_OUTPUT.PUT_LINE(ooo_cons2.xxx_sal); DBMS_OUTPUT.PUT_LINE(ooo_cons3.xxx_sal); END;
沒有留言:
張貼留言