【開發篇plsql】plsql物件型別

yellowlee發表於2010-06-05

2,plsql物件型別

物件導向的程式設計特別適合於構建可重用的元件和複雜應用。Plsql實現物件導向的程式設計是基於物件型別的。

使用物件型別可以對現實世界中的物件建模,分離介面和實現細節,並將物件導向的資料在資料庫中保持。

物件型別在結合使用如java類似的物件導向的程式語言是非常有用。

物件導向程式設計中有幾個重要的概念,包括抽象,屬性,方法,這些都可以在plsql中實現。

略去物件的概念和物件建模的細節,這些在大部分物件導向程式設計中已經有很好的描述和示例,直接來看plsql的實現。

plsql物件型別的結構主要有共有介面(public interface)和私有實現(private implementation)組成,

public interface中宣告屬性和方法,在private implementation中實現方法。簡單的例子:

create or replace type emp_sal as object

(

  sal  number,

  rate real,

  member function plus_sal(x emp_sal) return emp_sal,

  member function less_sal(x emp_sal) return emp_sal,

  member function get_sal return real,

  member function plus_sal(x real) return emp_sal,

  member procedure set_sal(x number),

  member function get_sal(x emp_sal) return emp_sal

)

;

 

 

create or replace type body emp_sal as

   member function plus_sal(x emp_sal) return emp_sal is

   begin

     return emp_sal(x.sal + x.sal * x.rate, x.rate);

   end;

 

  member function less_sal(x emp_sal) return emp_sal is

  begin

    return emp_sal(x.sal - x.sal * x.rate, x.rate);

  end;

 

  member function get_sal return real is

  begin

    return sal;

  end;

 

  member function plus_sal(x real) return emp_sal is

  begin

    return emp_sal(sal + sal * x, x);

  end;

 

  member procedure set_sal(x number) is

  begin

    sal := x;

  end;

 

  member function get_sal(x emp_sal) return emp_sal is

  begin

    return emp_sal(x.sal,x.rate);

  end;

 

end;

/

 

 

上面定義了一個emp_sal物件,擁有sal屬性和rate屬性,成員函式plus_sal按照比例來增加sal

Less_sal按照比例減salget_sal不做處理,返回salget_sal(x emp_sal)返回emp_sal物件, plus_sal(x real)過載了plus_sal(x emp_sal)

成員過程set_sal(x number)做設定sal的處理,不返回值。這裡先簡單描述,後面具體來看使用。

 

上述定義中的屬性和變數類似,其資料型別為oracle的資料型別,但是

long,long raw,rowed,urowid,binary_integer,Booleann,pls_interger,record,

ref cursor,%type%rowtype除外,且不能在定義屬性的時候初始化或者使用default值,

也不能使用not null約束。但是物件可以被儲存在有約束的資料庫表中。

 

宣告和初始化物件

以上面的type為例:

SQL> declare

  2    v_emp_sal emp_sal := emp_sal(1000,0.1);

  3  begin

  4    v_emp_sal.sal := 2000;

  5    v_emp_sal.rate := 0.15;

  6 

  7    dbms_output.put_line(v_emp_sal.sal||' '||v_emp_sal.rate);

  8 

  9  end;

 10  /

 

2000 .15

 

PL/SQL procedure successfully completed

 

方法或過程呼叫:

SQL> declare

  2    v_emp_sal emp_sal := emp_sal(1000,0.1);

  3  begin

  4    v_emp_sal.set_sal(2000);

  5    dbms_output.put_line('v_emp_sal.sal:'||v_emp_sal.sal);

  6    dbms_output.put_line('v_emp_sal.rate:'||v_emp_sal.rate);

  7    dbms_output.put_line('v_emp_sal.get_sal():'||v_emp_sal.get_sal());

  8 

  9    v_emp_sal := v_emp_sal.plus_sal(v_emp_sal);

 10    dbms_output.put_line('v_emp_sal.sal:'||v_emp_sal.sal);

 11    dbms_output.put_line('v_emp_sal.rate:'||v_emp_sal.rate);

 12 

 13    v_emp_sal := v_emp_sal.less_sal(v_emp_sal);

 14    dbms_output.put_line('v_emp_sal.sal:'||v_emp_sal.sal);

 15    dbms_output.put_line('v_emp_sal.rate:'||v_emp_sal.rate);

 16 

 17    v_emp_sal := v_emp_sal.plus_sal(0.5);

 18    dbms_output.put_line('v_emp_sal.sal:'||v_emp_sal.sal);

 19    dbms_output.put_line('v_emp_sal.rate:'||v_emp_sal.rate);

 20 

 21    v_emp_sal.sal := v_emp_sal.get_sal();

 22    dbms_output.put_line('v_emp_sal.get_sal():'||v_emp_sal.get_sal());

 23    dbms_output.put_line('v_emp_sal.sal:'||v_emp_sal.sal);

 24 

 25  end;

 26  /

 

v_emp_sal.sal:2000

v_emp_sal.rate:.1

v_emp_sal.get_sal():2000

v_emp_sal.sal:2200

v_emp_sal.rate:.1

v_emp_sal.sal:1980

v_emp_sal.rate:.1

v_emp_sal.sal:2970

v_emp_sal.rate:.5

v_emp_sal.get_sal():2970

v_emp_sal.sal:2970

 

PL/SQL procedure successfully completed

 

可以通過建立包含物件型別的表來使用sql操縱物件,例如上述例子可以建立一個這樣的表:

create table t_test_object_1 (

  id number ,

  col_emp_sal emp_sal

);

 

然後通過dml來操作物件,先插入一條測試資料:

SQL> insert into t_test_object_1 values (1,emp_sal(1000,.1));

 

1 row inserted

 

SQL> commit;

 

Commit complete

 

SQL>

 

使用select

SQL> select a.id, a.col_emp_sal.sal sal, a.col_emp_sal.rate rate

  2    from t_test_object_1 a;

 

        ID        SAL            RATE

---------- ---------- ---------------

         1       1000             0.1

 

使用物件emp_sal定義的方法的查詢:

SQL> select a.id,

  2         a.col_emp_sal.sal sal,

  3         a.col_emp_sal.rate rate,

  4         a.col_emp_sal.plus_sal(emp_sal(1200, .2)) .sal plus_sal1,

  5         a.col_emp_sal.plus_sal(emp_sal(1200, .2)) .rate plus_sal1_rate,

  6         a.col_emp_sal.plus_sal(0.2) .sal plus_sal2,

  7         a.col_emp_sal.get_sal() get_sal1,

  8         a.col_emp_sal.get_sal(emp_sal(2000, .15)) .sal get_sal2,

  9         a.col_emp_sal.get_sal(emp_sal(2000, .15)) .rate get_sal2_rate

 10    from t_test_object_1 a;

 

        ID        SAL    RATE  PLUS_SAL1 PLUS_SAL1_RATE  PLUS_SAL2   GET_SAL1   GET_SAL2 GET_SAL2_RATE

---------- ---------- ------- ---------- -------------- ---------- ---------- ---------- -------------

         1       1000     0.1       1440            0.2       1200       1000       2000          0.15

 

這樣有關屬性,方法的定義和使用就一目瞭然了。

同樣的,也可以使用updateinsert

SQL> update t_test_object_1 a

  2     set a.col_emp_sal.sal = 2000, a.col_emp_sal.rate = .2

  3   where a.id = 1;

 

1 row updated

 

SQL>

SQL> select a.id, a.col_emp_sal.sal sal, a.col_emp_sal.rate rate

  2    from t_test_object_1 a;

 

        ID        SAL      RATE

---------- ---------- ---------

         1       2000       0.2

 

SQL> rollback;

 

Rollback complete

 

SQL> delete t_test_object_1 a where a.col_emp_sal.sal = 1000;

 

1 row deleted

 

SQL> rollback;

 

Rollback complete

 

要注意的是一旦依賴物件型別建立了表,則objecttype定義不能更改或者drop,但是可以先drop掉關聯的表,然後再drop type

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16179598/viewspace-664433/,如需轉載,請註明出處,否則將追究法律責任。

相關文章