zoukankan      html  css  js  c++  java
  • 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 ef 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

  • 相关阅读:
    「JXOI2018」游戏
    「CTSC2018」假面
    CodeForces
    CodeForces
    [Lydsy1710月赛] 小B的数字
    OpenJ_Bailian
    [SDOI2010] 地精部落
    CodeForces
    CodeForces
    [NOI2009] 管道取珠
  • 原文地址:https://www.cnblogs.com/quzq/p/14276876.html
Copyright © 2011-2022 走看看