




已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Oracle嵌套表的使用一、嵌套表的定义: 嵌套表是表中之表。一个嵌套表是某些行的集合,它在主表中表示为其中的一列。对主表中的每一条记录,嵌套表可以包含多个行。在某种意义上,它是在一个表中存储一对多关系的一种方法。考查一个包含部门信息的表,在任何时间内每个部门会有很多项目正在实施。在一个严格的关系模型中,将需要建立两个独立的表department和project。嵌套表允许在department表中存放关于项目的信息。勿需执行联合操作,就可以通过department表直接访问项目表中的记录。这种不经联合而直接选择数据的能力使得用户对数据访问更加容易。甚至在并没有定义方法来访问嵌套表的情况下,也能够很清楚地把部门和项目中的数据联系在一起。在严格的关系模型中,department和project两个表的联系需要通过外部关键字(外键)关系才能实现。二、举例说明嵌套表的使用:假设有一个关于动物饲养员的表,希望其中具有他们饲养的动物的信息。用一个嵌套表,就可以在同一个表中存储饲养员和其饲养的全部动物的信息。1、创建类型animal_ty:此类型中,对于每个动物都包含有一个记录,记载了其品种、名称和出生日期信息。CREATE TYPE animal_ty AS OBJECT (breed varchar2(25), name varchar2(25), birthdate date); 2、创建animals_nt:此类型将用作一个嵌套表的基础类型。CREATE TYPE animals_nt as table of animal_ty;3、创建表breeder:饲养员的信息表create table breeder(breedername varchar2(25),animals animal_nt)nested table animals store as animals_nt_tab;4、向嵌套表中插入记录insert into breeder values(mary,animal_nt(animal_ty(dog,butch,31-MAR-97),animal_ty(dog,rover,31-MAR-97),animal_ty(dog,julio,31-MAR-97);insert into breeder values(jane,animal_nt(animal_ty(cat,an,31-MAR-97),animal_ty(cat,jame,31-MAR-97),animal_ty(cat,killer,31-MAR-97);commit;5、查询嵌套表select name,birthdate from table(select animals from breeder);select name,birthdate from table(select animals from breeder where breedername=mary)where name=dog;三、嵌套表的特点: 1、对象复用:如果编写面向对象的代码,就提高了重用以前编写的代码模块的机会。同样,如果创建面向对象的数据库对象,也就提高了数据库对象能够被重用的机会。2、标准支持:如果创建标准的对象,那么它们被重用的机会就会提高。如果有多个应用或多个表使用同一数据库对象集合,那么它就是既成事实的数据库对象标准。3、定义访问路径:对于每一个对象,用户可定义在其上运行的过程和函数,从而可以使数据和访问此数据的方法联合起来。有了用这种方式定义的访问路径,就可以标准化数据访问的方法并提高对象的可复用性。-以前在做报表的时候会经常用到oracle的内存表(其实是oracle嵌套表的部分功能,这里在下边介绍)来提高性能。利用oracle内存表进行临时运算通过ref cursor来返回我们想要的结果集。open cur for select * from table(fun_to_table_rb1_1(cur_qc,cur_qm);关于这部分的一些测试可以参看:/showthread.php?threadid=617298最近把oracle嵌套表的其他功能仔细看了看并做了个简单整理。oracle提供两种使用嵌套表的方法:1 PL/SQL代码中作为扩展PL/SQL语言;(这部分内容就是上边所说oracle内存表是oracle嵌套表的部分功能)2 作为物理存储机制,以持久地存储集合。*/-创建测试表:CREATE TABLE dept(deptno NUMBER(2) PRIMARY KEY, dname VARCHAR2(14), loc VARCHAR2(13); CREATE TABLE emp(empno NUMBER(4) PRIMARY KEY, ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4) REFERENCES emp, hiredate DATE, sal NUMBER(7,2), comm NUMBER(7,2), deptno NUMBER(2) REFERENCES dept); INSERT INTO dept SELECT * FROM scott.dept;INSERT INTO emp SELECT * FROM scott.emp;-创建typeCREATE OR REPLACE TYPE emp_type AS OBJECT(empno NUMBER(4), ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7,2), comm NUMBER(7,2); CREATE OR REPLACE TYPE emp_tab_type AS TABLE OF emp_type;-使用嵌套表CREATE TABLE dept_and_emp(deptno NUMBER(2) PRIMARY KEY, dname VARCHAR2(14), loc VARCHAR2(13), emps emp_tab_type)NESTED TABLE emps STORE AS emps_nest;-可以在嵌套表上增加约束(这里我们先不执行此步骤,等做完下一步测试我们再创建约束)-ALTER TABLE emps_nt ADD CONSTRAINT emps_empno_unique -嵌套表不支持参照完整性约束,不能参考任何其他表甚至自己-给嵌套表增加数据,我们看看这两种方式的结果有何不同方式1:INSERT INTO dept_and_empSELECT dept.*, CAST( MULTISET( SELECT empno, ename, job, mgr, hiredate, sal, comm FROM emp WHERE emp.deptno = dept.deptno ) AS emp_tab_type ) FROM dept;-Oracle同样提供方法去掉集合的嵌套,像关系型表一样处理(能够将EMPS列当作一个表,并自然连接且不需要连接条件):SELECT d.deptno, d.dname, emp.* FROM dept_and_emp D, TABLE(d.emps) emp;-这里执行看到结果是14条数据delete from dept_and_emp;方式2:INSERT INTO dept_and_emp SELECT dept.*, CAST(MULTISET( SELECT empno, ename, job, mgr, hiredate, sal, commFROM emp,dept WHERE emp.deptno = dept.deptno ) AS emp_tab_type ) from dept;SELECT d.deptno, d.dname, emp.* FROM dept_and_emp D, TABLE(d.emps) emp;-这里执行看到结果是56条数据,显然是错误的-第一个是按照where等连接条件符合的某一个dept的emp表的数据作为一个集合存储,而第二个没有任何关联条件,就是把所有emp的数据-全部作为一个dept的数据存储,这个写法显然是错误的,如果我们把刚才讲的约束给嵌套表加上,就可以起到防止这种错误的功效了。-增加约束再执行我们上边的第二个insert语句将会报错-我们按照上边第一个insert语句插入数据,继续我们下边的测试。-按照“每行实际是一张表”的思想来更新:UPDATE TABLE( SELECT emps FROM dept_and_emp WHERE deptno = 10) SET comm = 100;-插入与删除的语法:INSERT INTO TABLE(SELECT emps FROM dept_and_emp WHERE deptno=10)VALUES (1234,NewEmp,Clerk,7782,SYSDATE,1200,NULL); DELETE FROM TABLE(SELECT emps FROM dept_and_emp WHERE deptno=20)WHERE ename=SCOTT;-一般而言,必须总是连接,而不能单独查询嵌套表(如emp_nest)中的数据,但是如果确实需要,是可以的。-hint NESTED_TABLE_GET_REFS被用于EXP和IMP处理嵌套表。SELECT /*+NESTED_TABLE_GET_REFS+*/ NESTED_TABLE_ID, SYS_NC_ROWINFO$ FROM emps_nest;-而察看EMPS_NEST的结构看不到NESTED_TABLE_ID,SYS_NC_ROWINFO$两列。对父表DEPT_AND_EMP来说NESTED_TABLE_ID是一个外键。-使用这个hint就可以直接操作嵌套表了:UPDATE /*+NESTED_TABLE_GET_REFS+*/ emps_nest SET ename=INITCAP(ename);-嵌套表的存储:-上例中,现实产生了两张表:/*DEPT_AND_EMP(deptnob NUMBER(2),dname VARCHAR2(14),loc VARCHAR2(13),SYS_NC0000400005$,RAW(16)EMPS_NEST(SYS_NC_ROWINFO$,NESTED_TABLE_ID,RAW(16),empno NUMBER(4),ename VARCHAR2(10),job VARCHAR2(9),mgr NUMBER(4),hiredate DATE,sal NUMBER(7,2),comm NUMBER(7,2)*/ -默认情况下,每个嵌套表列都产生一个额外的RAW(16)隐藏列,并在其上创建了唯一约束,用以指向嵌套表。而嵌套表中有两个-隐藏列:SYS_NC_ROWINFO$是作为一个对象返回所有标量元素的一个伪列;另一个NESTED_TABLE_ID的外键回指向父表。-可以看到真实代码:/*CREATE TABLE DEPT_AND_EMP(DEPTNO NUMBER(2,0), DNAME VARCHAR2(14), LOC VARCHAR2(13), EMPS EMP_TAB_TYPE)PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 LOGGING STORAGE(INITIAL 131072 NEXT 131072MINEXTENTS 1 MAXEXTENTS 4096PCTINCREASE 0 FREELISTS 1 FREELIST GROUP 1BUFFER_POOL DEFAULT)TABLESPACE USERNESTED TABLE EMPSSTORE AS EMPS_NESTRETURN BY VALUE; RETURN BY VALUE用来描述嵌套表如何返回到客户应用程序中。NESTED_TABLE_ID列必须是索引的,那么较好的解决办法就是使用IOT存储嵌套表。CREATE TABLE DEPT_AND_EMP(DEPTNO NUMBER(2,0), DNAME VARCHAR2(14), LOC VARCHAR2(13), EMPS EMP_TAB_TYPE)PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 LOGGING STORAGE(INITIAL 131072 NEXT 131072MINEXTENTS 1 MAXEXTENTS 4096PCTINCREASE 0 FREELISTS 1 FREELIST GROUP 1BUFFER_POOL DEFAULT) TABLESPACE USERNESTED TABLE EMPSSTORE AS EMPS_NEST(empno NOT NULL,UNIQUE(empno),PRIMARY KEY(nested_table_id,empno)ORGANIZATION INDEX COMPRESS 1)RETURN BY VALUE; 这样与最初默认的嵌套表相比,使用了较少的存储空间并有最需要的索引。不使用嵌套表作为永久存储机制的原因1增加了RAW(16)列的额外开销,父表和子表都将增加这个额外的列;2当通常已经有唯一约束时,父表上的唯一约束是额外开销;3没有使用不支持的结构(NESTED_TABLE_GET_REFS),嵌套表不容易使用。一般推荐在编程结构和视图中使用嵌套表。如果要使用嵌套表作为存储机制,确保嵌套表是IOT,以避免NESTED_TABLE_ID和嵌套表本身中索引的额外开销。以上参考oracle高级专家编程。本文来自CSDN博客,转载请标明出处:/wxf82610/archive/2007/09/18/1789513.aspx-可变数组 一、可变数组的定义: 可变数组与嵌套表相似,也是一种集合。一个可变数组是对象的一个集合,其中每个对象都具有相同的数据类型。可变数组的大小由创建时决定。在表中建立可变数组后,可变数组在主表中作为一个列对待。从概念上讲,可变数组是一个限制了行集合的嵌套表。可变数组,允许用户在表中存储重复的属性。例如:假设用户有一个project表,并在项目中指定了工作人员,一个项目可以有多个工人,而一个工人也可以为多个项目工作。在严格的关系模型中,用户可以创建一个project表,一个worker表和存储它们之间关系的交叉表project_worker。用户可使用可变数组在project表中存储工人的名字。如果项目限定的工人数不超过10人,可以建立一个以10个数据项为限的可变数组。接下来就可处理此可变数组,从而对于每一个项目,可以选取其中所有工人的名字,而勿需查询表worker。二、举例说明可变数组的使用:1、创建类型comm_infoCREATE TYPE comm_info AS OBJECT ( /*此类型为通讯方式的集合no number(3), /*通讯类型号comm_type varchar2(20), /*通讯类型comm_no varchar2(30); /*号码2、创建可变数组comm_info_listCREATE TYPE comm_info_list AS VARRAY(50) OF comm_info;3、创建表create table user_info(user_id number(6), /*用户ID号user_name varchar2(20), /*用户名称user_comm comm_info_list); /*与用户联系的通讯方式4、向可变数组插入记录insert
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 石家庄市中医院医学伦理学在放射治疗中应用情景试题
- 张家口市人民医院肺功能临床意义考核
- 2025中心医院科室副主任年度绩效考核
- 2025河北唐山幼儿师范高等专科学校选聘工作人员35人考前自测高频考点模拟试题附答案详解(黄金题型)
- 2025金华市教育局所属金华教育学院公开招聘教师6人考前自测高频考点模拟试题附答案详解(考试直接用)
- 邯郸市人民医院巨乳缩小术技术专项考核
- 2025广东韶关市新丰县国有资产管理集团有限公司第一批专业技术人员招聘有关事项考前自测高频考点模拟试题附答案详解(模拟题)
- 唐山市人民医院角膜移植手术主刀资质评审
- 大学财务课件
- 2025中心医院皮肤撕裂伤处理考核
- 联想并购IBM案例分析
- 政府土地确权合同模板
- 铸件销售代理合同
- 足疗店禁止涉黄协议书模板
- 过敏性休克完整版本
- 齐次化妙解圆锥曲线(解析版)
- 九年级英语上学期第一次月考(广东卷)-2024-2025学年九年级英语全一册单元重难点易错题精练(人教版)
- 个人欠款协议书
- 方位角及坐标计算表格
- 人工智能基础与应用(第2版)全套教学课件
- FZT 62011.2-2016 布艺类产品 第2部分:餐用纺织品
评论
0/150
提交评论