Oracle PL/SQL存储过程对象类型Object type详解 create type obj_type as object, create table tab_name of obj_type

Myth丶恋晨 2022-04-10 07:14 943阅读 0赞

oracle 对象类型 object type

置顶 2011年06月13日 18:00:00 oypj2010 阅读数:3453

/* 对象类型属于用户自定义的一种复合类型,它封装了数据结构和拥有操作这些数据结构的函数。

  1. 对象类型;对象类型体和对象类型规范组成
  2. 对象类型属性不能使用以下类型定义。如;long,rowid,%type,%rowtype,ref cursor,record, pls\_integer
  3. 涉及到成员方法。构造方法,静态方法,map方法(将对象类型进行比较,因为对象不像标量那样可以直接排序),最大只能定义一个map 方法
  4. map方法可以对个对象进行排序,而order方法只能对两个对象实例比较大小 ,maporder不能同时定义。
  5. 1》对象表
  6. 对象表是包含对象类型列的表,而普通表其列全部使用标量数据类型。分为行对象表和列对象表
  7. 1.行对象表,
  8. eg; create table obj\_emp of emp\_type;
  9. 2.列对象(包含多个列)
  10. eg; create table obj\_emp(
  11. dno number,dname varchar2(10),
  12. emp emp\_type
  13. );
  14. 2》对象类型继承
  15. 3》引用对象类型 ref(指向对象的逻辑指针,是oracle的一种内置数据类型)(通过引用可以使不同表共享相同对象,从而降低内存占用)
  16. create table obj\_emp2 (
  17. dno number,
  18. emp ref obj\_emp --引用上面的行对象
  19. );
  20. 4》建立对象类型
  21. 1.建立无方法的对象类型
  22. create or replace type emp\_type as object (
  23. name varchar2(8),
  24. birthdate date
  25. );
  26. --建立行对象表
  27. create table emp\_tab of emp\_type ;
  28. --插入数据
  29. insert into emp\_tab values('tom',to\_date('1980-1-25','yyyy-mm-dd'));--普通插入
  30. insert into emp\_tab values(emp\_type('sam',to\_date('1983-1-25','yyyy-mm-dd'))); --采用对象类型构造方法插入
  31. -- pl/sql块中,如果要将对象数据检索到对象变量中,则必须用value方法
  32. declare
  33. emp emp\_type;
  34. begin
  35. select value(p) into emp from emp\_tab p where p.name = '&name';
  36. dbms\_output.put\_line(emp.birthdate);
  37. end;
  38. -- 更新行对象数据,如果根据对象属性更新数据时必须定义对象别名
  39. eg; update emp\_tab p set p.birthdate=to\_date('2000-1-23',yyyy-mm-dd) where p.name=&name;
  40. -- 删除行对象类型数据是如果根据对象属性删除数据 ,则删除时必须定义别名
  41. begin
  42. delete from emp\_tab p where p.name=&name;
  43. end;
  44. /
  45. ==============================================================================================
  46. -- 创建列对象表
  47. create or replace type emp\_l\_tab as object (
  48. dname varchar2(),emp emp\_type
  49. );
  50. -- insert (用对象类型的构造方法插入数据)
  51. insert into emp\_l\_tab values('db' emp\_type('tom',to\_date('2011-06-14',sysdate)));
  52. -- 检索列对象
  53. 检索行对象类型数据到类型变量时必须用value方法,但检索列对象时可以直接检索到类型变量
  54. declare
  55. v\_emp\_l emp\_type ;
  56. v\_dname varchar2(20) ;
  57. select dname,emp into v\_dname,emp from emp\_l\_tab b where b.dname=&dname;
  58. --更新列对象时,必须为列对象定义别名(列对象别名.对象类型列名.对象属性名)
  59. update emp\_l\_tab b set b.emp.birthdate = to\_date('2011-06-14','yyyy-mm-dd') where b.dname=&dame;
  60. --删除类同更新数据
  61. 2.建立有方法的对象类型
  62. 1 建立和使用member(成员)方法的对象类型(建立对象类型规范)
  63. eg;
  64. create or replace type emp\_m\_type as object(
  65. dname varchar2(20), ddate date,addr varchar2(100),
  66. member procdure proc\_change\_addr(newaddr dname),
  67. member function func\_get\_dname return varchar2
  68. );
  69. /
  70. 2》建立对象类型体
  71. create or replace type body emp\_m\_type is
  72. member procdure proc\_change\_addr(newaddr varchar2)
  73. is
  74. begin
  75. addr ;= newaddr;
  76. end;
  77. member function func\_get\_dname return varchar2
  78. is
  79. v\_dname varchar2(20);
  80. begin
  81. v\_danme := '部门:'||dname ||'--'|| birthdate ;
  82. return v\_danme;
  83. end;
  84. end;
  85. /
  86. -- 插入数据类同上面
  87. -- 提前数据
  88. declare
  89. v\_emp emp\_m\_type;
  90. begin
  91. v\_emp ;= emp.get\_dname('上海徐汇');
  92. ......................
  93. end;
  94. /
  95. --3 建立和使用static 方法
  96. static 方法用于访问对象类型,如果需要在对象类型上执行全局操作,则应该定义static
  97. 方法。只能有对象类型访问static
  98. create or replace type emp\_type3 as object(
  99. name varchar2(10),gender varchar2(2),
  100. static function getname return varchar2,
  101. member function get\_gender return varchar2
  102. );
  103. --建立对象类型体
  104. create or replace type body emp\_type3 is
  105. static function getname return varchar2 is
  106. begin
  107. return 'jecker';
  108. end;
  109. member function get\_gender return varchar2
  110. is
  111. begin
  112. return 'xingbie='||gender;
  113. end;
  114. end;
  115. ;
  116. -- 基于对象类型emp\_type3 建立 emp\_tab3
  117. create table emp\_tab3(
  118. eno number(6),emp emp\_type3,
  119. sal number(6,2),job varchar2(10)
  120. );
  121. -- 向表emp\_tab3插入数据
  122. begin
  123. insert into emp\_tab3(eno,sal,job,emp)
  124. values(100001,9999,'CTO/CIO',emp\_type3(
  125. 'jeckery',emp\_type3.getname()
  126. ));
  127. end;
  128. -- 访问 静态static函数和成员方法(member
  129. declare
  130. e emp\_type3;
  131. begin
  132. select t.emp into e from emp\_tab3 t where rownum=1;
  133. raise\_application\_error(-20201,emp\_type3.getname()||'-----'||e.get\_gender());
  134. end;
  135. -- 4.建立和使用 map 方法
  136. map方法用于将对象实例映射成标量值。
  137. -- 建立对象类型emp\_type4
  138. create or replace type emp\_type4 as object(
  139. name varchar2(10),
  140. birthdate date,
  141. map member function get\_birdate return varchar2
  142. );
  143. -- emp\_type4 对象类型实现方法体
  144. create or replace type body emp\_type4 is
  145. map member function get\_birdate return varchar2 is
  146. begin
  147. return trunc((sysdate-birthdate)/365);
  148. end;
  149. end;
  150. -- 根据对象类型empa\_type4 创建表emp\_tab4
  151. create table emp\_tab4 (
  152. eno number(6),sal number(6,2),
  153. job varchar2(20),emp4 emp\_type4
  154. );
  155. -- 插入数据到emp\_tab4
  156. begin
  157. insert into emp\_tab4(eno,sal,job,emp4)
  158. values(0011,9000,'dba',emp\_type4('jacker',to\_date('1990-12-19','yyyy-mm-dd')));
  159. insert into emp\_tab4(eno,sal,job,emp4)
  160. values(0022,9900,'dba',emp\_type4('jacker',to\_date('1970-12-2','yyyy-mm-dd')));
  161. end;
  162. --比较数据
  163. declare
  164. type emp4\_tab is table of emp\_type4;
  165. v\_emp4\_tab emp4\_tab;
  166. v\_result varchar2(100);
  167. begin
  168. select emp4 bulk collect into v\_emp4\_tab from emp\_tab4 ;
  169. if v\_emp4\_tab(1).get\_birdate()>v\_emp4\_tab(2).get\_birdate() then
  170. v\_result := v\_emp4\_tab(1).name ||' 比 '||v\_emp4\_tab(2).name ||'大';
  171. else
  172. v\_result := v\_emp4\_tab(1).name ||' 比 '||v\_emp4\_tab(2).name ||'小';
  173. end if;
  174. raise\_application\_error(-20201,v\_result);
  175. end;
  176. -- 5 建立order 方法
  177. 1.order map 在一个对象类型中不能同时存在
  178. 2.order 用于比较对象的2个实例大小
  179. -- 建立对象类型emp\_type4
  180. create or replace type emp\_type5 as object(
  181. name varchar2(10),
  182. birthdate date,
  183. order member function compare(emp5 emp\_type5) return int
  184. );
  185. -- emp\_type4 对象类型实现方法体
  186. create or replace type body emp\_type5 is
  187. order member function compare(emp5 emp\_type5) return int is
  188. begin
  189. case
  190. when birthdate>emp5.birthdate then return 1;
  191. when birthdate=emp5.birthdate then return 0;
  192. when birthdate<emp5.birthdate then return -1;
  193. end case;
  194. end;
  195. end;
  196. -- 根据对象类型empa\_type4 创建表emp\_tab4
  197. create table emp\_tab5 (
  198. eno number(6),sal number(6,2),
  199. job varchar2(20),emp5 emp\_type5
  200. );
  201. -- 插入数据到emp\_tab4
  202. begin
  203. insert into emp\_tab5(eno,sal,job,emp5)
  204. values(0011,9000,'dba',emp\_type5('jacker',to\_date('1990-12-19','yyyy-mm-dd')));
  205. insert into emp\_tab5(eno,sal,job,emp5)
  206. values(0022,9900,'dba',emp\_type5('tom',to\_date('1970-12-2','yyyy-mm-dd')));
  207. end;
  208. --比较数据
  209. declare
  210. type emp5\_tab is table of emp\_type5;
  211. v\_emp5\_tab emp5\_tab;
  212. v\_result varchar2(100);
  213. begin
  214. select emp5 bulk collect into v\_emp5\_tab from emp\_tab5 ;
  215. if v\_emp5\_tab(1).compare(v\_emp5\_tab(2))=1 then
  216. v\_result := v\_emp5\_tab(1).name ||' 比 '||v\_emp5\_tab(2).name ||'大';
  217. else
  218. v\_result := v\_emp5\_tab(1).name ||' 比 '||v\_emp5\_tab(2).name ||'小';
  219. end if;
  220. raise\_application\_error(-20201,v\_result);
  221. end;
  222. -- 6. 建立包含自定义对象类型的构造方法
  223. oracle 9i 开始可以自定义构造函数
  224. create or replace type emp\_type6 as object(
  225. name varchar2(10),birthdate date,
  226. constructor function emp\_type6(name,varchar2) return self as result;
  227. );
  228. 方法体的实现类同5
  229. ==========================================================================================
  230. 2》复杂对象类型
  231. 1.嵌套对象类型:一个对象类型中嵌套另一个对象类型
  232. create or replace typed emp\_addr\_type7 as object(
  233. addr varchar2(100)
  234. );
  235. eg;
  236. create or replace typed emp\_type7 as object(
  237. name varchar2(10), emp\_addr emp\_addr\_type7
  238. );
  239. 2.参照对象类型:建立对象表时 使用ref 定义表列,ref实际是指向对象数据的逻辑指针。
  240. ........
  241. 3》查看对象类型
  242. 1.查看对象类型
  243. select type\_name ,final from user\_types;
  244. 2.修改对象类型
  245. alter type emp\_type7 add atrribute addr varchar2(10) cascade;
  246. ...

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. CREATE TYPE BODY student_typ AS
  9. OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2 IS
  10. BEGIN
  11. RETURN (self AS person_typ).show || ' -- Major: ' || major ;
  12. END;
  13. END;
  14. /

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

  1. [https://blog.csdn.net/shcqupc/article/details/50684477][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.

他们坚持让你模拟现实世界的对象,单独的接口和实现细节,面向对象的数据和存储在数据库中。

  1. PL / SQL的声明和初始化对象

对象的类型可以代表任何真实世界的实体。例如,一个对象的类型可以代表一个学生,银行帐户,电脑屏幕上

,合理数量,或数据结构,如队列,堆栈,或列表。

[sql]

CREATE OR REPLACE TYPE address_typ AS OBJECT (

  1. street VARCHAR2(30),
  2. city VARCHAR2(20),
  3. state CHAR(2),
  4. postal\_code VARCHAR2(6)
  5. );

[sql]

CREATE OR REPLACE TYPE employee_typ AS OBJECT(

  1. employee\_id NUMBER(6),
  2. first\_name VARCHAR2(20),
  3. last\_name VARCHAR2(25),
  4. email VARCHAR2(25),
  5. phone\_number VARCHAR2(25),
  6. hire\_date DATE,
  7. job\_id VARCHAR2(25),
  8. salary NUMBER(8,2),
  9. commission\_pct NUMBER(2,2),
  10. manager\_id NUMBER(6),
  11. department\_id NUMBER(4),
  12. address address\_typ
  13. MAP MEMBER FUNCTION get\_idno RETURN NUMBER,
  14. MEMBER PROCEDURE display\_address(SELF IN OUT NOCOPY employee\_typ)
  15. );

--创建对象体

[sql]

CREATE TYPE BODY employee_typ AS

MAP MEMBER FUNCTION get_idno RETURN NUMBER IS

BEGIN

  1. RETURN employee\_id;

END;

MEMBER PROCEDURE display_address ( SELF IN OUT NOCOPY employee_typ ) IS

BEGIN

  1. DBMS\_OUTPUT.PUT\_LINE(first\_name || ' ' || last\_name);
  2. DBMS\_OUTPUT.PUT\_LINE(address.street);
  3. DBMS\_OUTPUT.PUT\_LINE(address.city || ', ' || address.state || ' ' ||
  4. address.postal\_code);

END;

END;

--持久化对象

[sql]

CREATE TABLE employee_tab OF employee_typ;

CREATE TYPE emp_typ as table of employee_typ;

  1. 在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’,

  1. '555.777.2222', to\_date('2012-12-24', 'yyyy-mm-dd'), 'SA\_MAN', 11000, .15, 101, 110,
  2. 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;

  1. 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

  1. 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

  1. DBMS\_OUTPUT.PUT\_LINE('emp.employee\_id is NULL \#2');

END IF;

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

  1. NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  2. 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

  1. DBMS\_OUTPUT.PUT\_LINE('emp.employee\_id is NULL \#3');

END IF;

EXCEPTION

WHEN ACCESS_INTO_NULL THEN

  1. DBMS\_OUTPUT.PUT\_LINE('Cannot assign value to NULL object');

END;

  1. 在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,

  1. address\_typ('123 Main', 'San Francisco', 'CA', '94111')) );

INSERT INTO employee_tab VALUES (employee_typ(320, ‘Martha’, ‘Dunn’, ‘MDUNN’,

  1. '555.111.3333', to\_date('2012-11-5', 'yyyy-mm-dd'), 'AC\_MGR', 12500, 0, 101, 110,
  2. 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,

  1. address\_typ('540 Fillmore', 'San Francisco', 'CA', '94011')) );

UPDATE employee_tab e SET e.address.street = ‘1040 California’

  1. WHERE e.employee\_id = 370;

DELETE FROM employee_tab e WHERE e.employee_id = 310;

END;

  1. 通过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;

  1. 定义相当于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’,

  1. CourseList('MATH1020')
  2. );

--查询

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

  1. VALUES(60, 'Security', 750400,
  2. ProjectList('New Badges', 'Track Computers', 'Check Exits'));
  1. 在动态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

  1. EXECUTE IMMEDIATE 'CREATE TABLE ' || tab\_name ||
  2. ' (pers person\_typ, hobbs hobbies\_var)';

END;

PROCEDURE insert_row (

  1. tab\_name VARCHAR2,
  2. p person\_typ,
  3. h hobbies\_var) IS

BEGIN

  1. EXECUTE IMMEDIATE 'INSERT INTO ' || tab\_name ||
  2. ' VALUES (:1, :2)' USING p, h;

END;

PROCEDURE print_table (tab_name VARCHAR2) IS

  1. TYPE refcurtyp IS REF CURSOR;
  2. v\_cur refcurtyp;
  3. p person\_typ;
  4. h hobbies\_var;

BEGIN

  1. OPEN v\_cur FOR 'SELECT pers, hobbs FROM ' || tab\_name;
  2. LOOP
  3. FETCH v\_cur INTO p, h;
  4. EXIT WHEN v\_cur%NOTFOUND;
  5. -- print attributes of 'p' and elements of 'h'
  6. DBMS\_OUTPUT.PUT\_LINE('Name: ' || p.name || ' - Age: ' || p.age);
  7. FOR i IN h.FIRST..h.LAST
  8. LOOP
  9. DBMS\_OUTPUT.PUT\_LINE('Hobby(' || i || '): ' || h(i));
  10. END LOOP;
  11. END LOOP;
  12. 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),

  1. hobbies\_var('skiing', 'coin collecting', 'tennis'));

TEAMS.insert_row(team_name, person_typ(‘Mary’, 28),

  1. 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

发表评论

表情:
评论列表 (有 0 条评论,943人围观)

还没有评论,来说两句吧...

相关阅读