侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

精通Oracle10编程SQL(15)使用对象类型

数据库  /  管理员 发布于 3年前   160

/* *使用对象类型 */--建立和使用简单对象类型--对象类型包括对象类型规范和对象类型体两部分。--建立和使用不包含任何方法的对象类型CREATE OR REPLACE TYPE person_typ1 as OBJECT(  name varchar2(10),gender varchar2(4),birthdate date);drop type person_typ1;--建立行对象(基于对象类型person_typ1)--行对象是指直接基于对象类型所建立的表--下面这条命令会建立行对象person_tab1create table person_tab1 of person_typ1;drop table person_tab1;--行对象结构与普通表没有任何区别select * from person_tab1;--为行对象插入数据begin     insert into person_tab1 values('马丽','女','11-1月-76');     --对象类型的构造方法来插入数据     insert into person_tab1 values(person_typ1('王鸣','男','12-4月-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);   dbms_output.put_line('出生日期:'||person.birthdate);end;--更新行对象数据--更新行对象数据时如果按照对象属性更新数据,则必须要为行对象定义别名。begin   update person_tab1 p set p.birthdate='11-2月-76' where p.name='马丽';end;--删除行对象数据--删除行对象数据时如果按照对象属性删除数据,则必须要为行对象定义别名。begin   delete from person_tab1 p where p.name='马丽';end;--建立列对象(包含对象类型person_typ1)--列对象是指在建表时指定了对象类型列的对象表CREATE TABLE employee_tab1(   eno number(6),person person_typ1,   sal number(6,2),job varchar2(12));drop table employee_tab1;select * from employee_tab1;--为列对象employee_tab1插入数据--为列对象插入数据时必须要使用对象类型的构造方法为对象列提供数据BEGIN     insert into employee_tab1(eno,sal,job,person) values(1,2000,'高级钳工',person_typ1('王鸣','男','01-8月-76'));END;--检索对象类型列的数据--检萦行对象数据到对象类型变量时必须要使用VALUE函数,而检索列对象的对象类型列数据时可以直接将对象实例数据检索到对象类型变量中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);   dbms_output.put_line('雇员工资:'||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;--建立和使用包含MEMBER方法的对象类型--建立对象类型规范person_typ2如下create or replace type person_typ2 as object(   name varchar2(12),gender varchar2(4),   birthdate date,address varchar2(100),   member procedure change_address(new_addr varchar2),   member function get_info return varchar2);drop type person_type2;--建立对象类型体person_typ2的示例如下CREATE OR REPLACE TYPE BODY person_typ2 is   member procedure change_address(new_addr varchar2)   is   begin     address:=new_addr;   end;   member function get_info return varchar2   is     v_info varchar2(100);   begin     v_info:='姓名:'||name||',出生日期:'||birthdate||',地址:'||address;     return v_info;   end;end;drop type body person_typ2;--在完成了对象类型person_typ2的创建工作之后,就可以使用该对象类型了--基于person_typ2建立对象表employee_tab2,并为其插入数据的示例如下create table employee_tab2(   eno number(6),person person_typ2,   sal number(6,2),job varchar2(18));select * from employee_tab2;drop table employee_tab2;insert into employee_tab2(eno,sal,job,person) values(1,2000,'高级焊工',person_typ2('王鸣','男','11-1月-75','深圳科技南路2号'));insert into employee_tab2(eno,sal,job,person) values(2,1500,'质量检查员',person_typ2('马丽','女','11-5月-75','深圳科技南路20号'));--下面以调用对象方法change_address改变人员地址为例,说明如何在PL/SQL块中使用对象方法DECLARE   v_person person_typ2;begin   select person into v_person from employee_tab2 where eno=&no;   v_person.change_address('深圳龙岗坂田基地');   update employee_tab2 set person=v_person where eno=&no;   dbms_output.put_line(v_person.get_info);end;--建立和使用包含STATIC方法的对象类型--建立对象类型规范person_typ3如下CREATE OR REPLACE TYPE person_typ3 as object(   name varchar2(10),gender varchar2(4),   birthdate date,regdate date,   static function getdate return date,   member function get_info return varchar2);drop type person_typ3;--建立对象类型体如下CREATE OR REPLACE TYPE BODY person_typ3 is  static function getdate return date is   begin    return sysdate;  end;  member function get_info return varchar2  is  begin    return '姓名:'||name||',注册日期:'||regdate;  end;end;--基于对象类型person_typ3建立对象表employee_tab3,并为其插入数据的示例如下CREATE TABLE employee_tab3(   eno number(6),person person_typ3,   sal number(6,2),job varchar2(18));--因为建立对象类型时定义了STATIC方法和MEMBER方法,所以在PL/SQL块中可以引用这些方法BEGIN   insert into employee_tab3(eno,sal,job,person)     values(&no,&salary,'&title',person_typ3(       '&name','&sex','&birthdate',person_typ3.getdate()   ));END;select * from employee_tab3;--建立和使用包含MAP方法的对象类型--MAP方法用于将对象实例映射为标量数值(NUMBER,DATE,VARCHAR2等)--注意:一个对象类型最多只能定义一个MAP方法,并且MAP方法和ORDER方法不能同时使用CREATE OR REPLACE TYPE person_typ4 as object(   name varchar2(10),gender varchar2(4),birthdate date,   map member function getage return varchar2);--建立对象类型体的示例CREATE OR REPLACE type body person_typ4 is    map member function getage return varchar2   is   begin      return trunc((sysdate-birthdate)/365);   end;end;--基于对象类型person_typ4建立对象表employee_tab4并为其插入数据的示例如下create table employee_tab4(   eno number(6),person person_typ4,   sal number(6,2),job varchar2(18));insert into employee_tab4(eno,sal,job,person)values(1,1500,'图书管理员',person_typ4('马丽','女','11-1月-76'));insert into employee_tab4(eno,sal,job,person)values(2,2000,'高级焊工',person_typ4('王鸣','男','11-5月-75'));insert into employee_tab4(eno,sal,job,person)values(3,2500,'高级工程师',person_typ4('李奇','男','11-5月-70'));select * from employee_tab4;--下面以比较对象表employee_tab4的前两条数据为例,说明使用MAP方法getage比较对象实例的方法DECLARE   TYPE person_table_type is table of person_typ4;   person_table person_table_type;   v_temp varchar2(100);begin   select person bulk collect into person_table from employee_tab4;   if person_table(1).getage()>person_table(2).getage() then      v_temp:=person_table(1).name||'比'||person_table(2).name||'大';   else      v_temp:=person_table(1).name||'比'||person_table(2).name||'小';   end if;   dbms_output.put_line(v_temp);end;--建立和使用包含ORDER方法的对象类型--ORDER方法用于比较两个对象实例的大小--注意:一个对象类型最多只能包含一个ORDER方法,并且ORDER方法不能与MAP方法同时使用CREATE OR REPLACE TYPE person_typ5 as object(name varchar2(10),gender varchar2(4),birthdate date,order member function compare(p person_typ5)return int);create or replace type body person_typ5 is   order member function compare(p person_typ5) 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;end;--基于对象类型person_typ5建立对象表employee_tab5,并为其插入两条数据create table employee_tab5(   eno number(6),person person_typ5,   sal number(6,2),job varchar2(18));insert into employee_tab5(eno,sal,job,person)values(1,1500,'图书管理员',person_typ5('马丽','女','11-1月-76'));insert into employee_tab5(eno,sal,job,person)values(2,2000,'高级焊工',person_typ5('王鸣','男','11-5月-75'));select * from employee_tab5;--下面以比较对象表employee_tab5的前两条数据为例,说明使用order方法compare比较对象实例的方法DECLARE    TYPE person_table_type is table of person_typ5;   person_table person_table_type;   v_temp varchar2(100);begin   select person bulk collect into person_table from employee_tab5;   if person_table(1).compare(person_table(2))=1 then      v_temp:=person_table(1).name||'比'||person_table(2).name||'大';   elsif person_table(1).compare(person_table(2))=0 then      v_temp:=person_table(1).name||'和'||person_table(2).name||'一样大';   else      v_temp:=person_table(1).name||'比'||person_table(2).name||'小';   end if;   dbms_output.put_line(v_temp);end;--建立和使用包含自定义构造方法的对象类型--注意,当自定义构造方法时,构造方法的名称必须要与对象类型的名称完全相同,并且必须要使用CONSTRUCTOR FUNCTION关键字定义构造方法--建立对象类型person_typ6的示例如下create or replace type person_typ6 as object(   name varchar2(10),gender varchar2(4),birthdate date,   constructor function person_typ6(name varchar2) return self as result,   constructor function person_typ6(name varchar2,gender varchar2) return self as result,   constructor function person_typ6(name varchar2,gender varchar2,birthdate date) return self as result);--建立对象类型体实现其构造方法CREATE OR REPLACE TYPE BODY person_typ6 is    constructor function person_typ6(name varchar2) return self as result   is   begin      self.name:=name;      self.gender:='女';      self.birthdate:=sysdate;      return;   end;      constructor function person_typ6(name varchar2,gender varchar2) return self as result   is   begin      self.name:=name;      self.gender:=gender;      self.birthdate:=sysdate;      return;   end;      constructor function person_typ6(name varchar2,gender varchar2,birthdate date) return self as result   is   begin      self.name:=name;      self.gender:=gender;      self.birthdate:=birthdate;      return;   end;end;--下面以基于对象类型person_typ5建立对象表,并使用各种构造方法为其插入数据为例,说明如何使用各种自定义构造方法create table employee_tab6(   eno number(6),person person_typ6,   sal number(6,2),job varchar2(18));insert into employee_tab6(eno,sal,job,person) values(1,1500,'图书管理员',person_typ6('马丽'));insert into employee_tab6(eno,sal,job,person) values(2,2000,'高级钳工',person_typ6('王鸣','男'));insert into employee_tab6(eno,sal,job,person) values(3,2500,'高级工程师',person_typ6('李奇','男','01-1月-70'));select * from employee_tab6;--建立和使用复杂对象类型--简单对象类型是指独立的并且与其他对象类型无关的对象类型,而复杂对象类型是指与其他对象类型具有关联关系的对象类型--对象类型嵌套--下面以建立和使用对象类型addr_typ7和person_typ7为例,说明如何建立和使用嵌套对象类型--建立对象类型addr_typ7create or replace type addr_typ7 as object(   state varchar2(20),city varchar2(20),   street varchar2(50),zipcode varchar2(8),   member function get_addr return varchar2);drop type addr_typ7;create or replace type body addr_typ7 as    member function get_addr return varchar2 is   begin      return state||city||street;   end;end;drop type body addr_typ7;--建立对象类型person_typ7create or replace type person_typ7 as object(   name varchar2(10),gender varchar2(4),   birthdate date,address addr_typ7,   member function get_info return varchar2);drop type person_typ7;create or replace type body person_typ7 as    member function get_info return varchar2   is   begin      return '姓名:'||name||',家庭住址:'||address.get_addr();   end;end;drop type body person_typ7;--建立并操纵对象表employee_tab7create table employee_tab7(   eno number(6),person person_typ7,   sal number(6,2),job varchar2(18));drop table employee_tab7;--操纵对象表employee_tab7--1.在PL/SQL块中为对象表插入数据begin   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')   ));end;select * from employee_tab7;--2.在PL/SQL块中更新对象列数据DECLARE   v_person person_typ7;begin   select person into v_person from employee_tab7 where eno=&no;   v_person.address.street:='&street';   update employee_tab7 set person=v_person where eno=&no;end;--3.在PL/SQL块中检索对象列数据DECLARE   v_person person_typ7;begin   select person into v_person from employee_tab7 where eno=&eno;   dbms_output.put_line(v_person.get_info);end;--4.在PL/SQL块中删除对象表数据begin     delete from employee_tab7 where eno=&no;end;--参照对象类型--参照对象类型是指在建立对象表时使用REF定义表列,REF实际是指向行对象数据的逻辑指针。--下面以建立对象类型person_typ8、行对象person_tab8和对象表employee_tab8为例,说明如何使用参照对象类型--建立对象类型person_typ8CREATE OR REPLACE TYPE person_typ8 as object(   name varchar2(10),gender varchar2(4),   birthdate date,address varchar2(50),   member function get_info return varchar2);create or replace type body person_typ8 as    member function get_info return varchar2   is   begin      return '姓名:'||name||',家庭住址:'||address;   end;end;--建立行对象person_tab8并追加数据create table person_tab8 of person_typ8;insert into person_tab8 values('马丽','女','11-1月-76','呼和浩特市北垣东街11号');insert into person_tab8 values('王鸣','男','11-2月-76','呼和浩特市呼伦南路21号');select * from person_tab8;--建立对象表employee_tab8--对象表employee_tab8用于存放雇员信息。因为person_tab8表已经包含了人员的部分信息,所以为了降低占用空间,employee_tab8表应该直接引用表person_tab8的数据create table employee_tab8(   eno number(6),person ref person_typ8,   sal number(6,2),job varchar2(18));drop table employee_tab8;select * from employee_tab8;--操纵对象表employee_tab8--1.为对象表插入数据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),2200,'高级钳工' from person_tab8 a where a.name='王鸣';end;--2.检索REF对象列数据--检索REF对象列数据时,因为该列实际存放的是指向行对象数据的指针,所以为了取得行对象的相应数据,必须要使用DEREF函数取得REF列所对应的实际数据DECLARE   v_person person_typ8;begin   select deref(person) into v_person from employee_tab8 where eno=&no;   dbms_output.put_line(v_person.get_info);end;--3.更新REF对象列数据DECLARE  v_person person_typ8;begin  select deref(person) into v_person from employee_tab8 where eno=&no;  v_person.address:='&address';  update person_tab8 set address=v_person.address where name=v_person.name;end;select * from person_tab8;select * from employee_tab8;--删除对象表数据begin   delete from employee_tab8 where eno=&no;end;--对象类型继承--当使用对象类型继承时,在定义父类型时必须要指定NOT FINAL选项,如果不指定该选项,默认选项为FINAL,表示该对象类型不能被继承--下面以建立父类型person_typ9,子类型employee_typ9,对象表employee_tab9为例,说明使用对象类型继承的方法--建立父对象类型person_typ9CREATE OR REPLACE type person_typ9 as object(   name varchar2(10),gender varchar2(4),   birthday date,address varchar2(50),   member function get_info return varchar2) not final;drop type person_typ9;create or replace type body person_typ9 as    member function get_info return varchar2   is   begin      return '姓名:'||name||',家庭住址:'||address;   end;end;drop type body person_typ9;--建立子对象类型employee_typ9create or replace type employee_typ9 under person_typ9(   eno number(6),sal number(6,2),job varchar2(18),   member function get_other return varchar2);drop type employee_typ9;create or replace type body employee_typ9 as   member function get_other return varchar2   is   begin      return '雇员名称:'||name||',工资:'||sal;   end;end;drop type body employee_typ9;--建立并操纵对象表employee_tab9--1.建立对象表并插入数据create table employee_tab9 of employee_typ9;drop table employee_tab9;select * from employee_tab9;insert into employee_tab9 values(   '马丽','女','11-1月-76','呼和浩特市北垣东街11号',   1,1500,'图书管理员');insert into employee_tab9 values(   '王鸣','男','11-2月-76','呼和浩特市呼伦南路21号',   2,2200,'高级钳工');select * from employee_tab9;--使用对象方法输出数据DECLARE   v_employee employee_typ9;begin   select value(a) into v_employee from employee_tab9 a where a.eno=&no;   dbms_output.put_line(v_employee.get_info);   dbms_output.put_line(v_employee.get_other);end;--维护对象类型--显示对象类型信息--通过查询数据字典视图USER_TYPES,可以显示当前用户所包含的所有对象类型的信息。--type_name用于标识对象类型的名称,attributes用于标识对象类型所包含的属性个数,而final用于标识对象类型是否可以作为父类型使用select type_name,attributes,final from user_types;select * from user_types;--在SQL*Plus中,通过执行DESC命令可以查看对象类型所包含的属性和方法DESC person_typ1;--增加和删除对象类型属性alter type person_typ1 add attribute address varchar2(50) cascade;alter type person_typ1 drop attribute birthdate cascade;--增加和删除对象类型方法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;

 


  • 上一条:
    精通Oracle10编程SQL(14)开发动态SQL
    下一条:
    精通Oracle10编程SQL(16)使用LOB对象
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • mysql5.7中实现分区表及分区where in查询示例及分区分表对比浅析(0个评论)
    • mysql中sql_mode的各模式浅析(0个评论)
    • 预处理之SQL参数化查询是如何防止SQL注入的浅析(0个评论)
    • 使用Navicat把mysql5.7版本的数据库导入至mysql8.1版本中流程步骤(0个评论)
    • 在mysql中设置表字段中COLLATE、CHARSET详解(0个评论)
    • 近期文章
    • 在go语言中使用GoPDF包把html生成PDF文件示例(0个评论)
    • 在go语言中创建和解析(读取)符号链接示例(0个评论)
    • ubuntu 22.04系统中报错:Python 3.6 is no longer supported by the Python core team...解决方式(0个评论)
    • Laravel 10.4版本发布(0个评论)
    • mysql5.7中实现分区表及分区where in查询示例及分区分表对比浅析(0个评论)
    • nginx + vue配置实现同域名下不同路径访问不同项目(0个评论)
    • 在laravel框架中的5个HTTP客户端技巧分享(0个评论)
    • 在go语言中使用FFmpeg库实现PCM音频文件编码为mp3格式文件流程步骤(0个评论)
    • gopacket免安装Pcap实现驱动层流量抓包流程步骤(0个评论)
    • 在laravel项目中实现密码强度验证功能推荐扩展包:password-strength(0个评论)
    • 近期评论
    • 博主 在

      2023年国务院办公厅春节放假通知:1月21日起休7天中评论 @ xiaoB 你只管努力,剩下的叫给天意;天若有情天亦老,..
    • xiaoB 在

      2023年国务院办公厅春节放假通知:1月21日起休7天中评论 会不会春节放假后又阳一次?..
    • BUG4 在

      你翻墙过吗?国内使用vpn翻墙可能会被网警抓,你需了解的事中评论 不是吧?..
    • 博主 在

      go语言+beego框架中获取get,post请求的所有参数中评论 @ t1  直接在router.go文件中配就ok..
    • Jade 在

      如何在MySQL查询中获得当月记录中评论 Dear zongscan.com team, We can skyroc..
    • 2017-06
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-01
    • 2018-05
    • 2018-10
    • 2018-11
    • 2020-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2021-02
    • 2021-04
    • 2021-07
    • 2021-08
    • 2021-11
    • 2021-12
    • 2022-02
    • 2022-03
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-03
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客