5.可变数组(解决有限的一对多的关系):
a.在单个行中存放单个数据的重复属性。
b.限制是可以存储的最大数目。
c.可变数组不能超过其限制。
d.可以基于抽象数据类型和Oracle标准数据类型。
e.缺点:更新时只能整个的更新。
(1)基于Oracle标准数据类型的数组:
Create type name as varray(4) of varchar2(10);
(2)基于抽象数据类型的可变数组:
SQL> create type AddressVary as varray(4) of AddressType;
2 /
--使用可变数组:
SQL> create table person(p_id int primary key,p_name varchar(10),address AddressVary);
--录入数据:
SQL> insert into person
2 values(1001,'wv',AddressVary(AddressType('China','xi an'),AddressType('China','qingdao')));
结果:
SQL> select * from person;
      P_ID P_NAME
---------- ----------
ADDRESS(COUNTRY, CITY)
--------------------------------------------------------------------------------
      1001 wv
ADDRESSVARY(ADDRESSTYPE('China', 'xi an'), ADDRESSTYPE('China', 'qingdao'))
--更新数据(必须更新整个可变数组):
SQL> update person set address=AddressVary(AddressType('China','beijing'))
   2 where p_id=1001;
6.嵌套表:
a.一个表表示成另一个表中的一列。
b.与可变数组类似,区别是嵌套表对数据项数目没有限制。
c.更新等操作能精确定位到嵌套表中的元组。
--定义供应商抽象数据类型:
SQL> create or replace type ProviderType as Object
2 (
3      pro_id int,
4      pro_name varchar2(20)
5 );
6 /
--以供应商来作为嵌套表抽象数据类型:
SQL> create type provider as table of ProviderType;
2        /
--创建商品嵌套表:
SQL> create table goods
2 (
3      g_id int primary key,
4      g_name varchar2(20),
5      g_pro provider
6 )nested table g_pro store as goods_provider;
--录入数据
SQL> insert into goods
2 values(1001,'oracledb',provider(ProviderType(1,'oracle'),ProviderType(2,'ibm')));
SQL> insert into table(select g_pro from goods g where g.g_id=1001) values(3,'sun');
SQL> select * from goods;
      G_ID G_NAME
---------- --------------------
G_PRO(PRO_ID, PRO_NAME)
--------------------------------------------------------------------------------
      1001 oracledb
PROVIDER(PROVIDERTYPE(1, 'oracle'), PROVIDERTYPE(2, 'ibm'), PROVIDERTYPE(3,     'sun'))
--查找数据:
(1)查找某个商品所有的供应商:
SQL> select * from
2 table(select x.g_pro from goods x where x.g_id=1001);
    PRO_ID PRO_NAME
---------- --------------------
      1     oracle
      2     ibm
      3       sun
--更新数据(更新某个商品的指定供应商):
SQL> update table(select x.g_pro from goods x where x.g_id=1002) y
2 set value(y)=ProviderType(2,'sun')
3 where y.pro_id=2;
--删除数据(删除指定商品的某个供应商):
SQL> delete from table(select x.g_pro from goods x where x.g_id=1001) y
2        where y.pro_id=2;
7.对象表:
a.一种特殊的表,表中的每一行都代表一个对象。
b.行对象:在对象表中拥有整个行的对象。
c.列对象:在较大的行中拥有某些表列的对象,或是其他对象的属性。
--创建对象表的抽象数据类型:
SQL> create type StuType as Object
2 (
3      sid int,
4      sname varchar2(20)
5 );
6 /
--创建对象表:
SQL> create table student of StuType;
--数据录入(两种方法):
SQL> insert into student values(1001,'wv');
SQL> insert into student values(StuType(1002,'zl'));
SQL> select value(t) from student t;
VALUE(T)(SID, SNAME)
-------------------------------------------
STUTYPE(1001, 'wv')
STUTYPE(1002, 'zl')
--更新和删除与关系表相同。
--ref 和 deref 的用法:
(1)ref :可以返回指向对象表中对象实例的指针。
(2)deref:使用ref数据类型作为自己的参数,返回对应的ref对象的实例。
--创建depart对象表:
SQL> create type DepartType as Object
2 (
3      dept_id int,
4      dept_name varchar2(20)
5 );
6 /
SQL> create table depart of DepartType;
表已创建。
--使用ref将新创建的worker表与对象表depart中的数据相关联:
SQL> create table worker
2 (
3      wok_id int,
4      wok_name varchar2(20),
5      wok_dept ref DepartType scope is depart
6 );
--数据录入(先录入depart,再录入worker):
SQL> insert into depart values(1001,'技术部');
SQL> insert into depart values(1002,'环卫部');
SQL> insert into worker select 1001,'wv',ref(a) from depart a where a.dept_id=1001;
SQL> select * from worker;
    WOK_ID WOK_NAME                      WOK_DEPT
-----------------------------------------------------------------------------
      1001 wv
00002202083C10A75CF0254AF7B9F199A01EEBDD038A24B220979848609498941C03665BEB
该查找找到了depart对象表中的OID(对象的HASH码),要想看到该对象的信息要用deref.
SQL> select wok_id,wok_name,deref(wok_dept) from worker;
    WOK_ID WOK_NAME      DEREF(WOK_DEPT)(DEPT_ID, DEPT_NAME)
-----------------------------------------------------------------------------------
      1002 zl                         DEPARTTYPE(1001, '技术部')
--数据更新(将wv的部门更新为环卫部)
1 update worker set wok_dept=(select ref(a) from depart a where a.dept_id=1002)
2* where wok_id=1001
--数据查询(查找所有环卫部门的员工)
(1)方法一:
SQL> select wok_id,wok_name,deref(wok_dept) from worker
2                     where wok_dept=(select ref(a) from depart a where a.dept_id=1002);
(2)方法二:
1 select wok_id,wok_name,deref(wok_dept) from worker
2* where wok_dept=(select ref(a) from depart a where value(a)=DepartType(1002,'环卫部'))
    WOK_ID WOK_NAME    DEREF(WOK_DEPT)(DEPT_ID, DEPT_NAME)
-------------------------------------------------------------------------------
      1001 wv                        DEPARTTYPE(1002, '环卫部')
--删除数据(环卫部门员工全部下岗):
SQL> delete from worker
2 where wok_dept=
3 (select ref(a) from depart a where value(a)=departType(1002,'环卫部'));
--悬空指针:
如果在对象表中删除被引用的实例,就会造成悬空ref,查询悬空的ref时就会显示null,使用is dangling 可以确定对应ref是否已经悬空。
SQL> delete from depart where dept_id=1001;
SQL> select wok_id,wok_name,deref(wok_dept) from worker where wok_dept is dangling;
    WOK_ID WOK_NAME    DEREF(WOK_DEPT)(DEPT_ID, DEPT_NAME)
----------------------------------------------------------------------
      1002    zl