oracle中對象類型搜集(object type)


/* 對象類型屬於用戶自定義的一種復合類型,它封裝了數據結構和擁有操作這些數據結構的函數。

    對象類型;對象類型體和對象類型規范組成
    對象類型屬性不能使用以下類型定義。如;long,rowid,%type,%rowtype,ref cursor,record, pls_integer等
    涉及到成員方法。構造方法,靜態方法,map方法(將對象類型進行比較,因為對象不像標量那樣可以直接排序),最大只能定義一個map 方法
    map方法可以對個對象進行排序,而order方法只能對兩個對象實例比較大小 ,map和order不能同時定義。
   
    《1》對象表
        對象表是包含對象類型列的表,而普通表其列全部使用標量數據類型。分為行對象表和列對象表
        1.行對象表,
          eg; create table obj_emp of emp_type;
        2.列對象(包含多個列)
          eg; create table obj_emp(
             dno number,dname varchar2(10),
             emp emp_type
          );
         
       《2》對象類型繼承  
       《3》引用對象類型 ref(指向對象的邏輯指針,是oracle的一種內置數據類型)(通過引用可以使不同表共享相同對象,從而降低內存占用)
             如 create table obj_emp2 (
                dno number,
                emp ref obj_emp  --引用上面的行對象
             );
         
        
      
       《4》建立對象類型
            1.建立無方法的對象類型
            create or replace type emp_type as object (
               name varchar2(8),
               birthdate date
            );
            --建立行對象表
            create table emp_tab of emp_type ;
            --插入數據
            insert into emp_tab values('tom',to_date('1980-1-25','yyyy-mm-dd'));--普通插入
            insert into emp_tab values(emp_type('sam',to_date('1983-1-25','yyyy-mm-dd'))); --采用對象類型構造方法插入
           
           -- 在pl/sql塊中,如果要將對象數據檢索到對象變量中,則必須用value方法
               declare
                 emp emp_type;
               begin
                  select value(p) into emp from emp_tab p where p.name = '&name';
                  dbms_output.put_line(emp.birthdate);
               end;
          
           -- 更新行對象數據,如果根據對象屬性更新數據時必須定義對象別名
               eg; update emp_tab p set p.birthdate=to_date('2000-1-23',yyyy-mm-dd) where p.name=&name;
          
           -- 刪除行對象類型數據是如果根據對象屬性刪除數據 ,則刪除時必須定義別名
               begin
                   delete from emp_tab p where p.name=&name;
               end;
               /
           
           ==============================================================================================  
            
             -- 創建列對象表
               create or replace type emp_l_tab as object (
                   dname varchar2(),emp emp_type
               );
             -- insert (用對象類型的構造方法插入數據)
               insert into emp_l_tab values('db' emp_type('tom',to_date('2011-06-14',sysdate)));
               
             -- 檢索列對象
                檢索行對象類型數據到類型變量時必須用value方法,但檢索列對象時可以直接檢索到類型變量
                 declare
                 v_emp_l emp_type ;
                 v_dname varchar2(20) ;
                 select dname,emp into v_dname,emp from emp_l_tab b where b.dname=&dname;
                 
            --更新列對象時,必須為列對象定義別名(列對象別名.對象類型列名.對象屬性名)
              update emp_l_tab b set b.emp.birthdate = to_date('2011-06-14','yyyy-mm-dd') where b.dname=&dame;
              
             --刪除類同更新數據
             
             
          
            2.建立有方法的對象類型
             1》 建立和使用member(成員)方法的對象類型(建立對象類型規范)
               eg;
               create or replace type emp_m_type as object(
                  dname varchar2(20), ddate date,addr varchar2(100),
                  member procdure proc_change_addr(newaddr dname),
                  member function  func_get_dname return varchar2
               );
               /
             2》建立對象類型體
               create or replace type body emp_m_type is
                 member procdure  proc_change_addr(newaddr varchar2)
                  is
                  begin
                    addr ;= newaddr;
                  end;
   
                 member function func_get_dname return varchar2
                  is
                    v_dname varchar2(20);
                  begin
                      v_danme := '部門:'||dname ||'--'|| birthdate ;
                    return v_danme;   
                  end;
                end;
                /
               
               -- 插入數據類同上面
               -- 提前數據
                  declare
                      v_emp emp_m_type;
                  begin
                     v_emp ;= emp.get_dname('上海徐匯');
                  ......................
                  end;
                  /
            
            
             --3 建立和使用static 方法
           static 方法用於訪問對象類型,如果需要在對象類型上執行全局操作,則應該定義static
           方法。只能有對象類型訪問static
             create or replace type emp_type3 as object(
                 name varchar2(10),gender varchar2(2),
                 static function getname return varchar2,
                 member function get_gender return varchar2
             );
          --建立對象類型體
           
             create or replace type body emp_type3 is
             static function getname return varchar2 is
             begin
               return 'jecker';
             end;
           
             member function get_gender return varchar2
              is 
              begin
                return 'xingbie='||gender;
              end;
           end;    
           ;

          -- 基於對象類型emp_type3 建立 emp_tab3 
          create table emp_tab3(
             eno number(6),emp emp_type3,
             sal number(6,2),job varchar2(10)
          );   
         
       -- 向表emp_tab3插入數據
            begin
              insert into emp_tab3(eno,sal,job,emp)
                values(100001,9999,'CTO/CIO',emp_type3(
                  'jeckery',emp_type3.getname()
                ));
            end;
             
      -- 訪問 靜態static函數和成員方法(member)
          declare 
            e emp_type3;
            begin 
               select t.emp into e from emp_tab3 t where rownum=1;
               raise_application_error(-20201,emp_type3.getname()||'-----'||e.get_gender());
            end;
                  
        
      
      -- 4.建立和使用 map 方法
       map方法用於將對象實例映射成標量值。
       
      -- 建立對象類型emp_type4
        create or replace type emp_type4 as object(
           name varchar2(10),
           birthdate date,
           map member function get_birdate return varchar2
        );

        -- 為emp_type4 對象類型實現方法體
        create or replace type body emp_type4 is
           map member function get_birdate return varchar2 is
           begin
             return trunc((sysdate-birthdate)/365);
           end;
         end;
                   
        -- 根據對象類型empa_type4 創建表emp_tab4
        create table emp_tab4 (
            eno number(6),sal number(6,2),
            job varchar2(20),emp4 emp_type4
        );
        -- 插入數據到emp_tab4           
        begin
          insert into emp_tab4(eno,sal,job,emp4) 
                  values(0011,9000,'dba',emp_type4('jacker',to_date('1990-12-19','yyyy-mm-dd')));
          insert into emp_tab4(eno,sal,job,emp4) 
                  values(0022,9900,'dba',emp_type4('jacker',to_date('1970-12-2','yyyy-mm-dd')));
        end; 

        --比較數據
        declare 
            type emp4_tab is table of  emp_type4;
             v_emp4_tab emp4_tab;
             v_result varchar2(100);
            begin
               select emp4 bulk collect into v_emp4_tab from emp_tab4 ;
                if v_emp4_tab(1).get_birdate()>v_emp4_tab(2).get_birdate() then 
                  v_result :=  v_emp4_tab(1).name ||' 比 '||v_emp4_tab(2).name ||'大';
                else
                    v_result := v_emp4_tab(1).name ||' 比 '||v_emp4_tab(2).name ||'小';
                end if;    
                raise_application_error(-20201,v_result);
            end;

        
        
        
        -- 5 建立order 方法
          1.order 與 map 在一個對象類型中不能同時存在
          2.order 用於比較對象的2個實例大小
          
          -- 建立對象類型emp_type4
            create or replace type emp_type5 as object(
               name varchar2(10),
               birthdate date,
               order member function compare(emp5 emp_type5) return int
            );

            -- 為emp_type4 對象類型實現方法體
            create or replace type body emp_type5 is
               order member function compare(emp5 emp_type5) return int is
               begin
                  case
                     when birthdate>emp5.birthdate then return 1;
                     when birthdate=emp5.birthdate then return 0;
                     when birthdate<emp5.birthdate then return -1;
                  end case;
               end;
             end;
                       
            -- 根據對象類型empa_type4 創建表emp_tab4
            create table emp_tab5 (
                eno number(6),sal number(6,2),
                job varchar2(20),emp5 emp_type5
            );
            -- 插入數據到emp_tab4           
            begin
              insert into emp_tab5(eno,sal,job,emp5) 
                      values(0011,9000,'dba',emp_type5('jacker',to_date('1990-12-19','yyyy-mm-dd')));
              insert into emp_tab5(eno,sal,job,emp5) 
                      values(0022,9900,'dba',emp_type5('tom',to_date('1970-12-2','yyyy-mm-dd')));
            end; 

            --比較數據
            declare 
                type emp5_tab is table of  emp_type5;
                 v_emp5_tab emp5_tab;
                 v_result varchar2(100);
                begin
                   select emp5 bulk collect into v_emp5_tab from emp_tab5 ;
                    if v_emp5_tab(1).compare(v_emp5_tab(2))=1 then 
                      v_result :=  v_emp5_tab(1).name ||' 比 '||v_emp5_tab(2).name ||'大';
                    else
                        v_result := v_emp5_tab(1).name ||' 比 '||v_emp5_tab(2).name ||'小';
                    end if;    
                    raise_application_error(-20201,v_result);
                end;

                      
          -- 6. 建立包含自定義對象類型的構造方法
           oracle 9i 開始可以自定義構造函數
            create or replace type emp_type6 as object(
                 name varchar2(10),birthdate date,
                constructor function emp_type6(name,varchar2) return self as result;
            );
           方法體的實現類同5
           
           
           ==========================================================================================
           《2》復雜對象類型
            1.嵌套對象類型:一個對象類型中嵌套另一個對象類型
               create or replace typed emp_addr_type7 as object(
                  addr varchar2(100)
               );   
            
              eg;
              create or replace typed emp_type7 as object(
                 name varchar2(10), emp_addr emp_addr_type7 
              );
              
            2.參照對象類型:建立對象表時 使用ref 定義表列,ref實際是指向對象數據的邏輯指針。
             ........
             
             
             
           《3》查看對象類型
              1.查看對象類型
                select type_name ,final from user_types;
              2.修改對象類型
               alter type emp_type7 add atrribute addr varchar2(10) cascade;
               ...

 

https://blog.csdn.net/oypj2010/article/details/6541972

 

 

 

 

 

Oracle type object 對象類型 繼承,參考官方文檔:

oracle create type object inherit

https://docs.oracle.com/en/database/oracle/oracle-database/18/adobj/inheritance-in-sql-object-types.html#GUID-A19D6DC9-5490-4EE5-B77C-1F734C86206D

2.3.5.2 Creating a Subtype Object

A subtype inherits the attributes and methods of the supertype.

These are inherited:

  • All the attributes declared in or inherited by the supertype.

  • Any methods declared in or inherited by supertype.

Example 2-15 defines the student_typ object as a subtype of person_typ, which inherits all the attributes declared in or inherited by person_typ and any methods inherited by or declared in person_typ.

Example 2-15 Creating a student_typ Subtype Using the UNDER Clause

  1.  
    -- requires Ex. 2-14
  2.  
    CREATE TYPE student_typ UNDER person_typ (
  3.  
    dept_id NUMBER,
  4.  
    major VARCHAR2(30),
  5.  
    OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2)
  6.  
    NOT FINAL;
  7.  
    /
  8.  
     
  9.  
    CREATE TYPE BODY student_typ AS
  10.  
    OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2 IS
  11.  
    BEGIN
  12.  
    RETURN (self AS person_typ).show || ' -- Major: ' || major ;
  13.  
    END;
  14.  
     
  15.  
    END;
  16.  
    /

The statement that defines student_typ specializes person_typ by adding two new attributes, dept_id and major and overrides the show method. New attributes declared in a subtype must have names that are different from the names of any attributes or methods declared in any of its supertypes, higher up in its type hierarchy.

https://docs.oracle.com/en/database/oracle/oracle-database/18/adobj/inheritance-in-sql-object-types.html#GUID-A19D6DC9-5490-4EE5-B77C-1F734C86206D

 

 

 

 

 

 

Oracle Object type 對象類型

2013年08月05日 12:17:11 維C番薯片 閱讀數:8292

版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/bbliutao/article/details/9765469

Oracle Object type 對象類型


一、概述
Oracle對象類型是Oracle面向對象程序設計的體現,它封裝了數據結構和用於操縱這些數據結構的過程和函數。


1、對象類型的組成
對象類型由兩部分組成——對象類型頭和對象類型體。
對象類型頭用於定義對象的公用屬性和方法;對象類型體用於實現對象類型頭所定義的公用方法。


2、對象類型屬性
定義對象類型最少要包含一個屬性,最多包含1000個屬性。定義時必須提供屬性名和數據類型,但不能指定默認值和not null。
數據類型不能包括long、long raw、rowid、urowid和PL/SQL特有類型(boolean\%type\%rowtype\ref curdor等)


3、對象類型的方法
定義對象類型可以包含也可以不包含方法,可以定義構造方法、member方法、static方法、map方法和order方法。


1)、構造方法
用於初始化對象並返回對象實例。構造方法是與對象類型同名的函數,默認的構造方法參數是對象類型的所有屬性。
9i前只能使用系統默認的構造方法、9i后可自定義構造函數,自定義必須使用constructor function關鍵字


2)、member方法
用於訪問對象實例的數據。當使用member方法時,可以使用內置參數self訪問當前對象實例。
當定義member方法時,無論是否定義self參數,它都會被作為第一個參數傳遞給member方法。
但如果要定義參數self,那么其類型必須要使用當前對象類型。member方法只能由對象實例調用,而不能由對象類型調用。


3)、static方法
用於訪問對象類型,可以在對象類型上執行全局操作,而不需要訪問特定對象實例的數據,因此static方法引用self參數。
static方法只能由對象類型調用,不能由對象實例調用(和member相反)。


4)、map方法
對象類型不同於標量類型可以直接比較,為了按照特定規則排序對象實例的數據,可以定義map方法,但只能有一個,與order互斥。
map方法將對象實例映射成標量數值來比較。


5)、order方法
map可以在對多個對象實例之間排序,而order只能比較2個實例的大小。定義對象類型時最多只能定義一個order方法,
而且map和order方法不能同時定義。使用原則是可不用則均不用,比較2個對象則用order,對個對象則用map。


4、對象表
對象表是指至少包含一個對象類型列的表。分為行對象表和列對象表。
行對象表是指直接基於對象類型所建立的表;列對象表則是只包含一個或多個列的對象表。


5、REF數據類型
ref是指向行對象的邏輯指針,是Oracle的一種內置數據類型。建表時通過使用REF引用行對象,可以使不同表共享相同對象。
例如:create table department(dno number(2),dname varchar2(10),emp ref employee_type)




二、對象類型的基本應用


1、概述
基本應用也屬於最常規、最簡單的應用,講述如何建立和使用獨立的並且與其他對象類型無關的對象類型。
包括語法、建立帶方法和不帶方法的對象類型。


2、語法
create or replace type type_name as object (
v_name1 datatype[,v_name2 datatype,...],
[member|static method1 spec,member|static method2 spec,...]);


create or replace type body type_name as
member|static method1 body;
member|static method1 body;...
其中,type_name是對象類型的名稱,v_name是屬性名稱,datatype是屬性數據類型,method是方法的名稱,body是PL/SQL的方法實現代碼。
如果定義對象類型頭時沒有定義方法,則不需要建立對象類型體。


3、建立和使用不包含任何方法的對象類型
--建立對象類型
create or replace type person_typ1 as object(name varchar2(10),gender varchar2(2),birthdate date);


1)、對於行對象表
--建立行對象表
create table persong_tab1 of person_typ1;
--插入
begin
insert into person_tab1 values('馬麗','女','11-1月-76');--不用構造方法
insert into person_tab1 values(person_typ1('王鳴','男','12-2月-76'));--用構造方法
end;
--查詢,必須使用value函數取得行數據
declare
person person_typ1;
begin
select value(p) into person from person_tab1 p where p.name='&name';
dbms_output.put_line(person.gender||','||person.birthdate);
end;
--更新
begin
update person_tab1 p set b.birthdate='11-2月-76' where p.name='馬麗';
end;
--刪除
begin
delete from person_tab1 p where p.name='馬麗';
end;


2)、對於列對象表
--建立列對象表
create table employee_tab1(eno number(6),person person_typ1,sal number(6.2),job varchar2(10));
--插入,必須使用構造方法(默認構造方法)
begin
insert into employee_tab1(eno,sal,job,person) values(1,2000,'高級電工',person_typ1('王鳴','男'.'01-8月-76'));
end;
--查詢
declare
employee person_typ1;
salary number(6,2);
begin
select person,sal into employee,salary from employee_tab1 where eno=&no;
dbms_output.put_line(employee.name||','||salary);
end;
--更新
begin
update employee_tab1 p set p.person.birthdate='&newdate' where p.person.name='&name';
end;
--刪除
begin
delete from employee_tab1 p where p.person.name='王鳴';
end;


4、建立和使用包含方法的對象類型


--建立對象類型頭
create or replace type person_typ2 as object
(
  name      varchar2(10),
  gender    varchar2(2),
  birthdate date,
  address   varchar2(100),
  regdate   date,
  member procedure change_address(new_addr varchar2),--member方法
  member function get_info return varchar2,--member方法
  static function getdate return date,--static方法
  map member function getage return varchar2,--map方法
  order member function compare(p person_typ2) return int,--order方法
  constructor person typ2(name varchar2) return self as result,
  constructor person typ2(name varchar2,gender varchar2) return self as result
);
--建立對象類型體
create or replace type body person_typ2 is
  member procedure change_address(new_addr varchar2) is
  begin
    address := new_addr; --member方法體現之處,直接訪問修改對象實例的數據address
  end;
  member function get_info return varchar2 is
    v_info varchar2(100);
  begin
    v_info := name || ',' || birthdate || ',' || regdate;
    return v_info;
  end;
  static function gerdate return date is
  begin
    return sysdate;
  end;
  map member function getage return varchar2 is
  begin
  return trunc((sysdate-birthdate)/365);--比較的依據是按照時間
  end;
  order member function compare(p person_typ2) return int is
  begin
  case
  when birthdate>p.birthdate then return 1;
  when birthdate=p.birthdate then return 0;
  when birthdate>p.birthdate then return -1;
    end case;
  end;
  constructor function person_typ2(name varchar2) return self as result is
  begin
  self.name:=name;
  self.gender:='女';
  self.birthdate:=sysdate;
  return;
  end;
  constructor function person_typ2(name varchar2,gender varchar2) return self as result is
  begin
  self.name:=name;
  self.gender:=gender;
  self.birthdate:=sysdate;
  return;
  end;
end;


--建立列對象表
create table employee_tab2(eno number(6),person person_typ2,sal number(6,2),job varchar2(10));
--插入
insert into employee_tab2(eno,sal,job,person) values(1,1500,'圖書管理員',
person_typ2('馬麗','女','11-1月-75','呼和浩特11號',person_typ2.getdate()));--由對象類型調用的全局方法getdate(static方法)
insert into employee_tab2(eno,sal,job,person) values(2,2000,'高級焊工',
person_typ2('王鳴','男','11-5月-75','呼和浩特21號',person_typ2.getdate()));
insert into employee_tab2(eno,sal,job,person) values(3,3000,'高級工程師',
person_typ2('李奇','男','11-5月-70','呼和浩特31號',person_typ2.getdate()));
insert into employee_tab2(eno,sal,job,person) values(3,3000,'高級工程師',person_typ2('怪獸');--自定義構造方法
insert into employee_tab2(eno,sal,job,person) values(3,3000,'高級工程師',person_typ2('怪獸','男');
--調用
declare
  v_person person_typ2;
  type person_table_type is table of person_typ2;
  person_table person_table_type;
begin
  select person into v_person from employee_tab2 where eno = &&no;
  v_person.change_address('呼和浩特12號');
  update employee_tab2 set person = v_person where eno = &no;
  dbms_output.put_line(v_person.get_info);
  --map,取表中前2條數據來對比
  select person bulk collect into person_table from employee_tab2;
  if person_table(1).getage()>person_table(2).getage() then
    dbms_output.put_line(person_table(1).name||'比'||person_table(2).name||'大');
  else
    dbms_output.put_line(person_table(2).name||'不比'||person_table(1).name||'大');
  end if;
  --compare
  if person_table(1).compare(person_table(2))=1 then
    dbms_output.put_line(person_table(1).name||'比'||person_table(2).name||'大');
  else
    dbms_output.put_line(person_table(2).name||'不比'||person_table(1).name||'大');
  end if;
end;




三、對象類型的高級應用


1、概述
高級應用簡述與其他對象類型具有關聯關系的對象類型。包括對象類型的嵌套、參照對象類型、對象類型的繼承。


2、對象類型的嵌套
1)、建立對象類型addr_typ7
create or replace type addr_typ7 as object(
state varchar2(20),city varchar2(20),street varchar2(50),zipcode(6),
member function get_addr return varchar2);


create or replace type body addr_typ7 as
  member function get_addr return varchar2 is
  begin
  return state||city||street;
  end;
end;


2)、建立對象類型person_typ7,嵌套addr_typ7對象類型
create or replace type person_typ7 as object(
name varchar2(10),gender varchar2(2),birthdate date,
address addr_typ7,member function get_info return varchar2);


create or replace type body person_typ7 as
  member function get_info return varchar2 is
  begin
  return '姓名:'||name||',家庭住址'||address.get_addr();
  end;
end;
  
3)、建立列對象表employee_tab7
create table employee_tab7(eno number(6),person person_typ7,sal number(6,2),job varchar2(10));


4)、插入
insert into employee_tab7(eno,sal,job,person) values
(1,1500,'圖書管理員',person_typ7('馬麗','女','01-11月-76',addr_typ7('內蒙古自治區','呼和浩特市','呼倫北路22號','010010')));
insert into employee_tab7(eno,sal,job,person) values
(2,2000,'高級鉗工',person_typ7('王鳴','男','11-12月-75',addr_typ7('內蒙古自治區','呼和浩特市','呼倫北路50號','010010')));


5)、更新
declare
  v_person person_typ7;
begin
select person into v_person from employee_tab7 where eno=1;
v_person.address.street:='北恆東街11號';
update employee_tab7 set person=v_person where eno=1;
end;


6)、查詢
declare
  v_person_typ7;
begin
select person into v_person from employee_tab7 where eno=1;
dbms_output.put_line(v_person.get_info);
end;


6)、刪除
begin
delete from employ33_tab7 where eno=1;
end;


3、參照對象類型
1)、概述
參照對象類型是指在建立對象表時使用REF定義表列,REF實際是指向行對象表數據的指針。
通過使用REF定義表列,可以使得一個對象表引用另一個對象表(行對象表)的數據。


2)、建立對象類型person_typ8
create or replace type person_typ8 as object(
name varchar2(10),gender varchar2(2),birthdate date,address varchar2(100),
member function get_info return varchar2
);


create or replace type body person_typ8 as
  member function get_info return varchar2 is
  begin
    return name||',0'||address;
  end;
end;


3)、建立行對象表person_tab8
create table person_tab8 of person_typ8;
insert into person_tab8 values('馬麗','女','11-1月-75','呼和浩特11號');
insert into person_tab8 values('王鳴','男','11-5月-75','呼和浩特21號');


4)、建立列對象表employee_tab8
說明:employee_tab8表直接引用person_tab8表的數據。
create table employee_tab8(
eno number(6),person ref person_typ8,sal number(6,2),job varchar2(10));


5)、插入
說明:因為employee_tab8的定義使用ref引用了person_tab8,所以插入需要引用該表數據。,使用函數REF
begin
  insert into employee_tab8 select 1,ref(a),2000,'圖書管理員' from person_tab8 a where a.name='馬麗';
  insert into employee_tab8 select 2,ref(a),2000,'高級鉗工' from person_tab8 a where a.name='王鳴';
end;


6)、查詢
說明:取ref對象列數據,必須使用deref。
declare
  v_person person_typ8;
begin
  select deref(person) into v_person from employee_tab8 where eno=1;
  dbms_output.put_line(v_person.get_into);
end;


7)、更新
declare
  v_person person_typ8;
begin
  select deref(perosn) into v_person from employee_tab8 where eno=1;
  v_person.address:='呼和浩特市神馬路';
  update person_tab8 set address=v_person.address where name=v_person.name;
end;


8)、刪除
begin
  delete from employee_tab8 where eno=1;
end;


4、對象類型的繼承
1)、概述
9i新增,一個對象類型繼承另一個對象類型。定義需要被繼承的父類時需要指定not final,否則默認final,表示對象類型不能被繼承。


2)、建立對象類型person_typ9
create or replace type person_typ9 as object(
name varchar2(10),gender varchar2(2),birthdate date,address varchar2(100),
member function get_info return varchar2
) not final;


create or replace type body person_typ8 as
  member function get_info return varchar2 is
  begin
    return name||',0'||address;
  end;
end;


3)、建立子對象類型
create or replace type employee_typ9 under person_typ9(
eno number(6),sal number(6,2),job varchar2(10),
member function get_other return varchar2);


create or replace type body employee_typ9 as
  member function get_other return varchar2 is
  begin
    return name||','||sal;
  end;
end;


4)、建立行對象表
create table employee_tab9 of employee_typ9;
insert into person_tab8 values('馬麗','女','11-1月-75','呼和浩特11號',1,1500,'圖書管理員');
insert into person_tab8 values('王鳴','男','11-5月-75','呼和浩特21號',2,2000,'高級鉗工');


5)、查詢
declare
  v_employee employee_typ9;
begin
select value(a) into v_employee from employee_tab9 a where a.eno=1;
dbms_output.put_line(v_employee.get_info||','||v_employee.get_other);
end;


四、維護對象類型
1、顯示對象類型信息
select type_name,attributes,final from user_types;


2、增刪對象類型的屬性
alter type person_typ1 add attribute address varchar2(50) cascade;
alter type person_typ1 drop attribute birthdate cascade;
--cascade級聯更新依賴對象類型的對象類型和對象表。


3、增刪對象類型的方法
alter type person_typ1 add member function get info return varchar2 cascade;
create or replace type body person_typ1 as
  member function get_info return varchar2 is
  begin
 return name||','||address;
  end;
end;

 

原文:https://blog.csdn.net/bbliutao/article/details/9765469

          https://blog.csdn.net/shcqupc/article/details/50684477

 

 

 

 

 

 

 

 

Oracle TYPE OBJECT詳解

2014年06月13日 13:24:58 zml19910422 閱讀數:532

轉自:http://blog.csdn.net/indexman/article/details/8435426

以下同:

https://www.2cto.com/database/201212/179282.html

Oracle TYPE OBJECT詳解

2012-12-26 11:43:33            

收藏   我要投稿

 

Oracle TYPE OBJECT詳解

 

======================================================

最近在自學PL/SQL高級編程,了解到對象類型(OBJECT TYPE)。

  www.2cto.com  

特意搜索了一下10G官方文檔,下面不才基於此進行拓展:

 

=======================================================

1. 介紹

Object-oriented programming is especially suited for building reusable components and complex

applications. 

 

尤其適合於構建可重用的部件和復雜的應用程序的面向對象的編程。

  www.2cto.com  

In PL/SQL, object-oriented programming is based on object types.

 

在PL / SQL,面向對象的程序設計是基於對象類型。

 

They let you model real-world objects, separate interfaces and implementation details, and store

object-oriented data persistently in the database.

他們堅持讓你模擬現實世界的對象,單獨的接口和實現細節,面向對象的數據和存儲在數據庫中。

 

2. PL / SQL的聲明和初始化對象

對象的類型可以代表任何真實世界的實體。例如,一個對象的類型可以代表一個學生,銀行帳戶,電腦屏幕上

 

,合理數量,或數據結構,如隊列,堆棧,或列表。

 

[sql] 

CREATE OR REPLACE TYPE address_typ AS OBJECT (  

       street          VARCHAR2(30),                       

       city            VARCHAR2(20),  

       state           CHAR(2),                              

       postal_code     VARCHAR2(6)    

        );  

 

[sql] 

CREATE OR REPLACE TYPE employee_typ AS OBJECT(  

       employee_id       NUMBER(6),  

       first_name        VARCHAR2(20),  

       last_name         VARCHAR2(25),  

       email             VARCHAR2(25),  

       phone_number      VARCHAR2(25),  

       hire_date         DATE,  

       job_id            VARCHAR2(25),                                                     

       salary            NUMBER(8,2),                

       commission_pct    NUMBER(2,2),                                                     

       manager_id        NUMBER(6),                                                     

       department_id     NUMBER(4),                                                     

       address           address_typ                                                     

       MAP MEMBER FUNCTION get_idno RETURN NUMBER,                                                     

       MEMBER PROCEDURE display_address(SELF IN OUT NOCOPY employee_typ)  

       );  

 

 

--創建對象體

[sql] 

CREATE TYPE BODY employee_typ AS  

  MAP MEMBER FUNCTION get_idno RETURN NUMBER IS  

  BEGIN  

    RETURN employee_id;  

  END;  

  MEMBER PROCEDURE display_address ( SELF IN OUT NOCOPY employee_typ ) IS  

  BEGIN  

    DBMS_OUTPUT.PUT_LINE(first_name || ' '  || last_name);  

    DBMS_OUTPUT.PUT_LINE(address.street);  

    DBMS_OUTPUT.PUT_LINE(address.city || ', '  || address.state || ' ' ||  

                         address.postal_code);     

  END;  

END;  

 

--持久化對象

[sql] 

CREATE TABLE employee_tab OF employee_typ;  

CREATE TYPE  emp_typ as table of employee_typ;  

 

3.  在PL/SQL塊中聲明對象:

 

[sql] 

DECLARE  

  emp employee_typ; -- emp is atomically null  

BEGIN  

-- call the constructor for employee_typ  

  emp := employee_typ(315, 'Francis', 'Logan', 'FLOGAN',  

        '555.777.2222', to_date('2012-12-24', 'yyyy-mm-dd'), 'SA_MAN', 11000, .15, 101, 110,  

         address_typ('376 Mission', 'San Francisco', 'CA', '94222'));  

  DBMS_OUTPUT.PUT_LINE(emp.first_name || ' ' || emp.last_name); -- display details  

  emp.display_address();  -- call object method to display details  

END;  

 

4.  PL/SQL如何處理未初始化的對象:

 

[sql] 

DECLARE  

  emp employee_typ; -- emp is atomically null  

BEGIN  

  IF emp IS NULL THEN DBMS_OUTPUT.PUT_LINE('emp is NULL #1'); END IF;  

  IF emp.employee_id IS NULL THEN  

     DBMS_OUTPUT.PUT_LINE('emp.employee_id is NULL #1');  

  END IF;  

  emp.employee_id := 330;  

  IF emp IS NULL THEN DBMS_OUTPUT.PUT_LINE('emp is NULL #2'); END IF;  

  IF emp.employee_id IS NULL THEN  

    DBMS_OUTPUT.PUT_LINE('emp.employee_id is NULL #2');  

  END IF;  

  emp := employee_typ(NULL, NULL, NULL, NULL,  

        NULL, NULL, NULL, NULL, NULL, NULL, NULL,  

         address_typ(NULL, NULL, NULL, NULL));  

  -- emp := NULL; -- this would have made the following IF statement TRUE  

  IF emp IS NULL THEN DBMS_OUTPUT.PUT_LINE('emp is NULL #3'); END IF;  

  IF emp.employee_id IS NULL THEN  

    DBMS_OUTPUT.PUT_LINE('emp.employee_id is NULL #3');  

  END IF;  

EXCEPTION  

   WHEN ACCESS_INTO_NULL THEN  

     DBMS_OUTPUT.PUT_LINE('Cannot assign value to NULL object');  

END;  

 

5. 在PL/SQL中操縱對象:

5.1.調用對象構造器和方法(Calling Object Constructors and Methods)

 

[sql] 

DECLARE  

  emp employee_typ;  

BEGIN  

  INSERT INTO employee_tab VALUES (employee_typ(310, 'Evers', 'Boston', 'EBOSTON',  

   '555.111.2222', to_date('2012-12-24', 'yyyy-mm-dd'), 'SA_REP', 9000, .15, 101, 110,  

    address_typ('123 Main', 'San Francisco', 'CA', '94111')) );  

  INSERT INTO employee_tab VALUES (employee_typ(320, 'Martha', 'Dunn', 'MDUNN',  

    '555.111.3333', to_date('2012-11-5', 'yyyy-mm-dd'), 'AC_MGR', 12500, 0, 101, 110,  

    address_typ('123 Broadway', 'Redwood City', 'CA', '94065')) );  

END;  

 

5.2  更新和刪除對象:

 

[sql] 

DECLARE  

  emp employee_typ;  

BEGIN  

  INSERT INTO employee_tab VALUES (employee_typ(370, 'Robert', 'Myers', 'RMYERS',  

   '555.111.2277', to_date('2012-3-7', 'yyyy-mm-dd'), 'SA_REP', 8800, .12, 101, 110,  

    address_typ('540 Fillmore', 'San Francisco', 'CA', '94011')) );  

  UPDATE employee_tab e SET e.address.street = '1040 California'  

     WHERE e.employee_id = 370;  

  DELETE FROM employee_tab e WHERE e.employee_id = 310;  

END;  

 

6.  通過REF修飾符操縱對象:

 

[sql] 

DECLARE  

  emp           employee_typ;  

  emp_ref   REF employee_typ;  

  emp_name      VARCHAR2(50);  

BEGIN  

  SELECT REF(e) INTO emp_ref FROM employee_tab e WHERE e.employee_id = 370;  

-- the following assignment raises an error, not allowed in PL/SQL  

-- emp_name := emp_ref.first_name || ' ' || emp_ref.last_name;  

-- emp := DEREF(emp_ref); not allowed, cannot use DEREF in procedural statements  

  SELECT DEREF(emp_ref) INTO emp FROM DUAL; -- use dummy table DUAL  

  emp_name := emp.first_name || ' ' || emp.last_name;  

  DBMS_OUTPUT.PUT_LINE(emp_name);  

END;  

 

7. 定義相當於PL/SQL集合類型的SQL類型(Defining SQL Types Equivalent to PL/SQL Collection Types)

 

7.1 定義嵌套表:

 

--建嵌套表類型

CREATE TYPE CourseList AS TABLE OF VARCHAR2(10)  -- define type

--建對象類型

CREATE TYPE student AS OBJECT (  -- create object

   id_num  INTEGER(4),

   name    VARCHAR2(25),

   address VARCHAR2(35),

   status  CHAR(2),

   courses CourseList);  -- declare nested table as attribute

--建立嵌套表類型表

CREATE TABLE sophomores of student

  NESTED TABLE courses STORE AS courses_nt;

--插入數據

insert into sophomores 

values(1,'dylan','CARL STREET','ACTIVE',

       CourseList('MATH1020')

      );

--查詢

SELECT  a.*, b.* 

from  sophomores a, TABLE(a.courses) b; 

 

select /*+ nested_table_get_refs */ * 

from courses_nt t;

 

7.2 定義數組:

-- 聲明數組類型(Each project has a 16-character code name)

-- We will store up to 50 projects at a time in a database column.

CREATE TYPE ProjectList AS VARRAY(50) OF VARCHAR2(16);

--創建表

CREATE TABLE dept_projects (  -- create database table

   dept_id  NUMBER(2),

   name     VARCHAR2(15),

   budget   NUMBER(11,2),

-- Each department can have up to 50 projects.

   projects ProjectList);

 

--插入數據:

  INSERT INTO dept_projects

    VALUES(60, 'Security', 750400,

      ProjectList('New Badges', 'Track Computers', 'Check Exits'));

 

 

8.  在動態SQL中使用對象:

8.1 定義對象類型person_typ和數組類型hobbies_var,並創建報TEAMS:

 

[sql] 

CREATE TYPE person_typ AS OBJECT (name VARCHAR2(25), age NUMBER);  

  

CREATE TYPE hobbies_var AS VARRAY(10) OF VARCHAR2(25);  

  

CREATE OR REPLACE PACKAGE teams  

   AUTHID CURRENT_USER AS  

   PROCEDURE create_table (tab_name VARCHAR2);  

   PROCEDURE insert_row (tab_name VARCHAR2, p person_typ, h hobbies_var);  

   PROCEDURE print_table (tab_name VARCHAR2);  

END;  

  

CREATE OR REPLACE PACKAGE BODY teams AS  

   PROCEDURE create_table (tab_name VARCHAR2) IS  

   BEGIN  

      EXECUTE IMMEDIATE 'CREATE TABLE ' || tab_name ||  

                        ' (pers person_typ, hobbs hobbies_var)';  

   END;  

   PROCEDURE insert_row (  

      tab_name VARCHAR2,  

      p person_typ,  

      h hobbies_var) IS  

   BEGIN  

      EXECUTE IMMEDIATE 'INSERT INTO ' || tab_name ||  

         ' VALUES (:1, :2)' USING p, h;  

   END;  

   PROCEDURE print_table (tab_name VARCHAR2) IS  

      TYPE  refcurtyp IS REF CURSOR;  

      v_cur refcurtyp;  

      p     person_typ;  

      h     hobbies_var;  

   BEGIN  

      OPEN v_cur FOR 'SELECT pers, hobbs FROM ' || tab_name;  

      LOOP  

         FETCH v_cur INTO p, h;  

         EXIT WHEN v_cur%NOTFOUND;  

         -- print attributes of 'p' and elements of 'h'  

         DBMS_OUTPUT.PUT_LINE('Name: ' || p.name || ' - Age: ' || p.age);  

         FOR i IN h.FIRST..h.LAST  

         LOOP  

           DBMS_OUTPUT.PUT_LINE('Hobby(' || i || '): ' || h(i));  

         END LOOP;  

      END LOOP;  

      CLOSE v_cur;  

   END;  

END;  

 

 

8.2 調用TEAMS包中的存儲過程:

 

 

 

[sql] 

DECLARE  

   team_name VARCHAR2(15);  

BEGIN  

   team_name := 'Notables';  

   TEAMS.create_table(team_name);  

   TEAMS.insert_row(team_name, person_typ('John', 31),  

      hobbies_var('skiing', 'coin collecting', 'tennis'));  

   TEAMS.insert_row(team_name, person_typ('Mary', 28),  

      hobbies_var('golf', 'quilting', 'rock climbing', 'fencing'));  

   TEAMS.print_table(team_name);  

END;  

 

=================================================

output:

Name: John - Age: 31

Hobby(1): skiing

Hobby(2): coin collecting

Hobby(3): tennis

Name: Mary - Age: 28

Hobby(1): golf

Hobby(2): quilting

Hobby(3): rock climbing

Hobby(4): fencing

 

PL/SQL 過程已成功完成。

https://www.2cto.com/database/201212/179282.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM