標籤:
------------------------抽象資料類型-----------
--建立地址類型,一定要加as object,還可以在類型中加過程或方法
create or replace type address as object (
province varchar2(10), --省份屬性
city varchar2(10) --市屬性
) not final; --not final表示該類型可以有子類型
--定義一個子類型
--under address說明這個類型繼承至address類型
create or replace type detailAddress under address (
street varchar2(20) --街道屬性 第3個成員
);
--建立員工資訊表,最後一列是detailAddress類型
drop table empInfo
create table empInfo (
eName varchar2(20) , --員工姓名
eSex char(2), --性別
eAge int, --年齡
eAddress detailAddress --員工地址
);
--增加資料,只能用構造方法
insert into empInfo values(‘aaa‘, ‘男‘, 28, detailAddress(‘湖北‘, ‘襄樊‘, ‘八一路‘));
insert into empInfo values(‘bbb‘, ‘男‘, 26, detailAddress(‘湖北‘, ‘武漢‘, ‘永清街‘));
insert into empInfo values(‘ccc‘, ‘女‘, 29, detailAddress(‘湖北‘, ‘武漢‘, ‘光穀‘));
--查詢
select * from empInfo;
select * from empInfo where eSex = ‘男‘;
select * from empInfo e where e.eAddress.city = ‘武漢‘; --如果查詢條件包含屬性必須用表的別名
--更新有2種方式:
--第一種方式:整體更新
update empInfo e set e.eAddress = detailAddress(‘湖北‘, ‘武漢‘, ‘武昌‘) where e.eName = ‘ccc‘;
--第二種方式:只更新抽象類別型的某一列
update empInfo e set e.eAddress.city = ‘武漢‘ where e.eName = ‘ccc‘;
--刪除
delete from empInfo e where e.eAddress.city = ‘武漢‘;
--為抽象資料類型的屬性建立索引
create index idxemp on empInfo(eAddress.city);
--刪除
drop table empInfo;
drop type address force; --強制移除抽象類別型
-------------------------------抽象資料類型結束----------------------
------------------對象表,表中的每一行就是一個對象-----------------------
--建立抽象資料類型person,並作為基底類型
create or replace type person as object (
pName varchar2(20), --姓名
pSex char(2), --性別
pAge int --年齡
) not final;
--建立子類型student,繼承person
--後面不要加as object
create or replace type student under person (
stuId int
);
--建立對象表stuInfo
create table stuInfo of student;
--為對象表建立主鍵約束
alter table stuInfo add constraint pk_stuInfo primary key(stuId);
--插入資料,當普通表插入
insert into stuInfo values(‘aaa‘, ‘男‘, 29, 1001);
--插入資料,用構造方法
insert into stuInfo values(student(‘bbb‘, ‘男‘, 26, 1002));
insert into stuInfo values(student(‘ccc‘, ‘女‘, 29, 1003));
--查詢,當普通表用
select * from stuInfo where stuId = 1002;
--更新和刪除都用普通的sql語句即可
update stuInfo set pAge = 29 where pName = ‘ccc‘;
delete from stuInfo where stuId = 1001;
rollback;
--ref(表別名)函數用來返回對象的OID,也就是物件識別碼,對象表也有rowid
select ref(s) from stuInfo s;
select rowid, ref(s) OIDS from stuInfo s;
--建立學生分數表,注意外鍵
create table stuScore (
stu ref student, --stu這一列的值必須出現在stuInfo表中,且stu這一列存的對象的OID而不是對象本身
score int --分數
);
--向分數表插入資料,只能用select,不能用普通的values
--錯誤的做法:insert into stuscore values(select ref(s) from stuInfo where stuId = 1001, 90)
--正確的做法:
insert into stuscore select ref(s), 90 from stuInfo s where stuId = 1001;
insert into stuscore select ref(s), 80 from stuInfo s; --插入3行資料
insert into stuscore select ref(s), 70 from stuInfo s where stuId = 1003;
--查詢
select * from stuScore;
--deref(列名)函數可以把OID還原為對象,主鍵列顯示有問題
select deref(s.stu), score from stuScore s where s.stu.stuId = 1001;
--修改,以下2個都可以
update stuScore set score=100 where stu = (select ref(s) from stuInfo s where stuId = 1001);
update stuScore s set score = 99 where s.stu.stuId = 1001;
--刪除,以下3個都可以
delete from stuScore where stu = (select ref(s) from stuInfo s where stuId = 1001);
delete from stuScore s where s.stu.stuId = 1001;
delete from stuScore where stuId = 1001;
----------------------------------對象表結束----------------------
----------------------------------物件檢視-----------------------
--物件檢視的作用:把已經存在的關係錶轉換為對象表來使用,原表沒有變
--首先要建立一個和原表一樣的類型
--然後建立視圖
create table aaa
(a int);
create type aaaa as object
(a int);
create or replace view view_stu of aaaa with object oid(a)
as
select * from aaa;
select * from view_stu;
--增刪改查都和對象表一樣
-------------------------------物件檢視結束-----------------------
--------------------------------抽象類別型,包含過程和方法-------------
create or replace type ADDRESS as object (
province varchar2(10), --省份
city varchar2(10), --市,後面的,不能少
member function get_pro return varchar2, --函數,後面接,而不是;
member function get_city return varchar2,
member procedure set_pro(pro varchar2), --過程
member procedure set_city(cy varchar2)
);
create or replace type body ADDRESS--後面不能加 as object
as --後面不能加begin
member function get_pro return varchar2
is
begin
return province;
end get_pro;
member function get_city return varchar2
is
begin
return city;
end;
member procedure set_pro(pro varchar2)
is
begin
province := pro;
end;
member procedure set_city(cy varchar2)
is
begin
city := cy;
end;
end;
--測試上面的成員函數和過程
declare
addr address;
begin
addr := address(‘湖北‘, ‘武漢‘);
dbms_output.put_line(addr.get_city);
end;
--drop table stuInfo;
create table stuInfo (
stuId int primary key,
addr address
);
declare
addr address;
begin
addr := address(‘湖北‘, ‘武漢‘);
insert into stuInfo values(1, addr);
addr.set_city(‘鄭州‘);
addr.set_pro(‘河南‘);
insert into stuInfo values(2, addr);
end;
select * from stuInfo;
--刪除類型
drop type address force;
--------------------------抽象類別型,包含過程和方法 結束-------------
----------------------------可變數組------------------------------
--就是一個可以儲存多個值的有最大長度的數組,數組的成員可以是任意類型
--建立一個可變數群組類型,長度是10,存放的資料類型是number(4)
create or replace type arrType as varray(10) of number(4);
create or replace type scoreType as object (
subName varchar2(10),
score int
);
--建立一個長度為10的可變數組,存放資料類型是scorType
create or replace type arrScoreType as varray(10) of scoreType;
--建立學生資訊表
--drop table stuInfo;
create table stuInfo (
stuId int primary key,
score arrScoreType --可變數組,最多10個成員
);
--插入資料,用可變數組的建構函式
insert into stuInfo values(1, arrScoreType(
scoreType(‘sql‘, 50), scoreType(‘C#‘, 80), scoreType(‘java‘, 90)));
insert into stuInfo values(2, arrScoreType(
scoreType(‘sql‘, 60), scoreType(‘C#‘, 85), scoreType(‘java‘, 95), scoreType(‘html‘, 60)));
insert into stuInfo values(3, arrScoreType(
scoreType(‘sql‘, 70), scoreType(‘java‘, 93)));
--查詢
select * from stuInfo; --查詢結果是集合
--如何才能查詢出可變數組裡的資料呢?思路是:用table函數把集合轉化為表,然後再從這個表查詢資料
select * from table(select s.score from stuInfo s where s.stuId = 2);
--table函數裡面只能是一個可變數組
select s.stuId, t.* from stuInfo s,
table(select score from stuInfo where stuId = s.stuId) t
where s.stuId = 2;
--更新,整個可變數組一起更新,不能只更新數組的某個元素
update stuInfo set score = arrScoreType(
scoreType(‘sql‘, 50), scoreType(‘C#‘, 80)) where stuId = 1;
--刪除,按主鍵刪除
-----------------------------可變數組結束---------------------------------
drop type scoreType force;
drop type arrScoreType force;
drop table stuInfo;
-----------------------------巢狀表格---------------------------
--建立抽象類別型
create or replace type scoreType as object (
subName varchar2(10),
score int
);
--建立巢狀表格類型
create or replace type nestTable is table of scoreType;
--建立包含巢狀表格的學生資訊表
create table stuInfo (
stuId int,
score nestTable --其實存的是引用,實際資料存在abc表中
) nested table score store as abc;
--nested table score store as abc意思是:stuInfo這個表中的score這一列是巢狀表格類型,巢狀表格實際是存在abc這個表中
--增刪和可變數組一樣
insert into stuInfo values(3, nestTable(
scoreType(‘sql‘, 70), scoreType(‘java‘, 93)));
--查詢,思路:把巢狀表格先查出來,然後把巢狀表格和stuInfo進行聯集查詢
select * from table(select ss.score from stuInfo ss where stuId = 3);
select s.stuId, t.* from stuInfo s, table(select ss.score from stuInfo ss where stuId = s.stuId) t
where s.stuId = 3;
--更新
update table(select ss.score from stuInfo ss where stuId=3) t
set t.score = 80 where t.subName = ‘sql‘;
--刪除
delete from table(select ss.score from stuInfo ss where stuId = 3) t
where t.subname=‘sql‘;
----可變數組和巢狀表格的異同----------------
相同點:
1、都是抽象類別型
2、都可以作為表中某列的資料類型(record和快表是不能作為列的資料類型的)
不同點:
1、可變數組本身就存放在原表中,而巢狀表格存放在另外的表中
2、可變數組有大小限制,而巢狀表格沒有
3、可變數組更新時必須更新整個可變數組,而巢狀表格更新時可以只更新巢狀表格中的部分記錄
Oracle筆記 十二、PL/SQL 物件導向oop編程