Oracle自定义数据类型 1
原文 oracle 自定義類型 type / create type
一 Oracle中的類型
類型有很多種,主要可以分為以下幾類:
1、字符串類型。如:char、nchar、varchar2、nvarchar2。
2、數值類型。如:int、number(p,s)、integer、smallint。
3、日期類型。如:date、interval、timestamp。
4、PL/SQL類型。如:pls_integer、binary_integer、binary_double(10g)、binary_float(10g)、boolean。plsql類型是不能在sql環境中使用的,比如建表時。
5、自定義類型:type / create type。
二 type / create type 區別聯系
相同:
可用用關鍵字create type 或者直接用type定義自定義類型,
區別:
create type 變量 as table of 類型
--
create type 變量 as object(
字段1 類型1,
字段2 類型2
);
--------------------------
與 type 變量 is table of 類型
--
type 變量 is record(
字段1 類型1,
字段2 類型2
);
區別是 用 create 后面用 as , 若直接用 type 后面用 is
create 是創 object , 而 type 是創 record .
另 type用在語句塊中,而create 是的獨立的.
?
?
一般定義object的語法:
用
create type 自定義表類型A as table of 自定義Object類型A
和
create type 自定義Object類型A as object(
字段1 類型1,
字段2 類型2
);
?
與
type 自定義表類型B is table of 類型
和
type 自定義Object類型B is record(
字段1 類型1,
字段2 類型2
);
自定義類型一般分為兩中,object類型和table類型.object類似于一個recored,可以表示一個表的一行數據,
object的字段就相當與表的字段.
自定義的table類型需要用的已經定義好的object類型.
?
三 type record用法概述
type 自定義Object類型B is record(
字段1 類型1,
字段2 類型2
);
3.1:什么是記錄(Record)?
由單行多列的標量構成的復合結構。可以看做是一種用戶自定義數據類型。組成類似于多維數組。
將一個或多個標量封裝成一個對象進行操作。是一種臨時復合對象類型。
記錄可以直接賦值。RECORD1 :=RECORD2;
記錄不可以整體比較.
記錄不可以整體判斷為空。
3.2:%ROWTYPE和記錄(Record)?
請區別%ROWTYPE和記錄(Record)類型。%ROWTYPE可以說是Record的升級簡化版。
區別在與前者結構為表結構,后者為自定義結構。二者在使用上沒有很大區別。前者方便,后者靈活。在實際中根據情況來具體決定使用。
Record + PL/SQL表可以進行數據的多行多列存儲。
3.3:如何創建和使用記錄?
?①創建記錄類型
?
?語法:
?
TYPE 記錄名 IS RECORD (filed1 type1 [NOT NULL] [:=eXPr1],....... ,filedN typen [NOT NULL] [:=exprn] )其中,filed1是標量的名字。
?②聲明記錄類型變量:
? 記錄類型變量名 記錄類型
?③填充記錄。
?④訪問記錄成員
? 記錄類型變量名.filed1
? .........
? 記錄類型變量名.filedN
?
注意:
表字段類型修改后,還需要修改記錄字段類型,有時候可能會忘記,從而出現錯誤。
對于記錄內每個字段(filed1.。。。),可以指定也可以使用%TYPE和%ROWTYPE動態指定記錄字段類型。
好處是表字段發生變化,記錄字段自動改變。但是,由于每次執行前,遇到%TYPR或%ROWTYPE,
數據庫系統都會去查看對應表字段類型,會造成一定的數據庫開銷,如果系統中大量使用記錄類型,則對性能會有一定影響。
另外如果刪除了某一字段,而自定義記錄中使用了該字段,也會有可能忘記刪除該字段。
對數據庫負荷偏低的系統,性能問題一般可以不重點關注,但是對于高負荷數據庫服務器,
各個環節都要考慮性能問題,每處節省一點出來,性能整體就有很大提高。
?
語法:
?
TYPE 記錄名 IS RECORD (filed1 table.Filed%Type [NOT NULL] [:=eXPr1] ,filed2 table.Filed%Type [NOT NULL] [:=eXPr1] ,....... ,filedn table.Filed%Type [NOT NULL] [:=exprn] );?
例子:記錄可以整體賦值
?
/*conn scott/tigerCreate Table empa As Select * From emp;*/DeclareType EmpType is Record(EMPNO number(4),ENAME varchar2(10),JOB varchar2(15),SAL number(7,2),DEPTNO number(2));EmpRec1 EmpType;EmpRec2 EmpType;BeginEmpRec1.Empno:=7369;EmpRec1.Ename:='SMITH';EmpRec1.Job:='CLERK';EmpRec1.Sal:=800;EmpRec1.Deptno:=10;EmpRec2 := EmpRec1;DBMS_output.put_line(EmpRec2.empno);End;?
例子:記錄不可以整體比較,只可以比較記錄字段
?
DeclareType EmpType is Record(EMPNO number(4),ENAME varchar2(10),JOB varchar2(15),SAL number(7,2),DEPTNO number(2));EmpRec1 EmpType;EmpRec2 EmpType;BeginEmpRec1.Empno:=7369;EmpRec1.Ename:='SMITH';EmpRec1.Job:='CLERK';EmpRec1.Sal:=800;EmpRec1.Deptno:=10;if EmpRec1.sal < EmpRec2.sal thenDBMS_output.put_line('Xiao Xiao Xiao');end if;End;?
例子:記錄不可以整體判斷為空,只可以判斷記錄字段。
?
DeclareType EmpType is Record(EMPNO number(4),ENAME varchar2(10),JOB varchar2(15),SAL number(7,2),DEPTNO number(2));EmpRec EmpType;Beginif EmpRec.ename is null thenDBMS_output.put_line('Kong Kong Kong');end if;End;?
例子:使用%TYPE和%ROWTYPE動態指定記錄字段。
/*conn scott/tiger Create Table empa As Select * From emp; */ DECLAREType MyRecType Is Record(RENO EMPA.EMPNO%Type,RENAME EMPA.ENAME%Type,RJOB EMPA.JOB%Type);EmpRec MyRecType; BeginSelect EMPNO, ENAME, JOB InTo EmpRec From empa Where empa.EMPNO = '7369';If EmpRec.RJOB = 'CLERK' ThenDBMS_OUTPUT.PUT_LINE('Name: '||EmpRec.RENAME);End If; End;例子:數據集中的記錄和記錄類型中的數據關系。
?
DECLAREType MyRecType Is Record(RENO EMPA.EMPNO%Type,RENAME EMPA.ENAME%Type,RJOB EMPA.JOB%Type);EmpRec MyRecType;vJob EMPA.JOB%Type;BeginSelect EMPNO, ENAME, JOB InTo EmpRec From empa Where empa.EMPNO = '7369';DBMS_OUTPUT.PUT_LINE('MyRecType.RJOB: '||EmpRec.RJOB);EmpRec.RJOB := '修改值后' ;DBMS_OUTPUT.PUT_LINE('MyRecType.RJOB: '||EmpRec.RJOB);Select JOB InTo vJob from empa Where empa.EMPNO = EmpRec.RENO;DBMS_OUTPUT.PUT_LINE('EMPA.JOB: '||vJob);End;/?
3.4:使用記錄向表中插入數據?
根據表結構合理安排記錄字段。比如主外鍵。
如果用記錄(RECORD)插入數據,那么只能使用記錄成員;
如果用%ROWTYPE插入數據,可以直接使用%ROWTYPE。
例子:使用記錄成員向表中插入數據
?
DECLAREType MyRecType Is Record(RENO EMPA.EMPNO%Type,RENAME VARCHAR2(10),RJOB EMPA.JOB%Type);EmpRec MyRecType; BeginSelect EMPNO, ENAME, JOB InTo EmpRec From empa Where empa.EMPNO = '7369';DBMS_OUTPUT.PUT_LINE(EmpRec.RENO||' '||EmpRec.RENAME||' '||EmpRec.RJOB);EmpRec.RENO := 1001;EmpRec.RENAME := '杰克';EmpRec.RJOB := '辦事員';Insert InTo empa(EMPNO,ENAME,JOB) Values(EmpRec.RENO, EmpRec.RENAME,EmpRec.RJOB);Select EMPNO, ENAME, JOB InTo EmpRec From empa Where empa.EMPNO = '1001';DBMS_OUTPUT.PUT_LINE(EmpRec.RENO||' '||EmpRec.RENAME||' '||EmpRec.RJOB); End;?
3.5:使用記錄更新數據?
如果用記錄(RECORD)更新數據,那么只能使用記錄成員;
如果用%ROWTYPE更新數據,可以直接使用%ROWTYPE。
例子:使用%ROWTYPE向表中插入數據
DECLAREvEmp empa%RowType; BeginSelect * InTo vEmp From empa Where empa.EMPNO = '7369';UpDate empa Set ROW = vEmp Where EMPNO = 1001; End;3.6:使用記錄刪除數據?
刪除記錄時,只能在delete語句的where子句中使用記錄成員。
?
四 type table用法
4.1:定義
type 變量 is table of 類型
TYPE orders_type IS TABLE OF all_orders%ROWTYPE;
4.2:用法
1. TYPE tabletype IS TABLE ?OF type INDEX BY BINARY_INTEGER;
定義:TYPE t_charTable IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;?
引用:tableName(index);?
例子:
declaretype t_table is table of varchar2(10) indexby BINARY_integer;MyTab t_table; beginMyTab(1) := 'A';MyTab(2) := 'B';MyTab(3) := 'C';DBMS_OUTPUT.PUT_LINE('First index:'||' '|| mytab(1) ||' '); end; -- DECLARETYPE t_StudentTable IS TABLE OF students%ROWTYPE INDEXBY BINARY_INTEGER;v_Students t_StudentTable; BEGIN SELECT * INTO v_Students(1100) FROM students WHERE id=1100;DBMS_OUTPUT.PUT_LINE( v_Students(1100).OUUSRNM); END;--record table綜合使用
/*conn scott/tigerCreate table empa as select * from emp; */ --例子: DeclareType RecType Is Record(rno empa.empno%type,rname empa.ename%type,rsal empa.sal%type);Type TabType Is Table Of RecType Index By Binary_Integer;MyTab TabType;vN Number; Begin--填充vN := 1;For varR In (Select * From empa Order By empno ASC)LoopMyTab(vN).rno := varR.empno;MyTab(vN).rname := varR.ename;MyTab(vN).rsal := varR.sal;vN := vN + 1;End Loop;--訪問vN := MyTab.First;For varR In vN..MyTab.countLoopDBMS_OUTPUT.PUT_LINE(vN ||' '||MyTab(vN).rno||' '||MyTab(vN).rname||' '||MyTab(vN).rsal);vN := MyTab.Next(vN);End Loop; End;?
注意:
Oracle中index by binary_integer的作用
如語句:type ?numbers ?is table of number index by binary_integer;其作用是,加了”index by binary_integer ”后,numbers類型的下標就是自增長,numbers類型在插入元素時,不需要初始化,不需要每次extend增加一個空間。而如果沒有這句話“index by binary_integer”,那就得要顯示對初始化,且每插入一個元素到numbers類型的table中時,都需要先extend.
示例, 沒加“index by binary_integer”時:
declare type numbers is table of number; n numbers := numbers(); begin n.extend; n(1) := 2; n.extend; n(2) := 3; for i in1 .. n.count loop dbms_output.put_line(n(i)); end loop; end; --輸出:2,3而如果加了“index by binary_integer”,代碼如下寫就可以達到上面的效果
declaretype numbers is table of number index by binary_integer;n numbers;beginn(1) := 2;n(2) := 3;for i in1 .. n.count loopdbms_output.put_line(n(i));end loop;end;?
五 create type 用法
5.1 定義
概念 ?
?方法:是在對象類型說明中用關鍵字 ?MEMBER ? 聲明的子程序 ? ?
?方法是作為對象類型定義組成部分的一個過程或函數 ? ?
?方法不能與對象類型或其任何屬性同名 ? ?
?與數據包程序相似,大多數方法有兩個部分?
?
CREATE [OR REPLACE] TYPE <typename> AS OBJECT (attribute1 datatype,:attributeN datatypeMEMBER PROCEDURE <methodname> (parameter, mode, datatype),MEMBER FUNCTION <methodname> (parameter, mode, datatype)RETURN datatype,PRAGMA RESTRICT_REFERENCES(<methodname>,WNDS/RNDS/WNPS/RNPS) );?
?說明:PRAGMA ? RESTRICT_REFERENCES指定MEMBER方法按以下模式之一 ? 操作:
? –WNDS ? (不能寫入數據庫狀態) ? 不能修改數據庫 ? ?
?–RNDS ? (不能讀出數據庫狀態) ? 不能執行查詢 ? ?
?–WNPS ? (不能寫入數據包狀態) ? 不能更改數據包變量的值 ? ?
?–RNPS ? (不能讀出數據包狀態) ? 不能引用數據包變量的值 ? ?
?例:
create or replace type FLIGHT_SCH_TYPE as object ( FLIGHTNO VARCHAR2(4) , AIRBUSNO VARCHAR2(5) , ROUTE_CODE VARCHAR2(7) , DEPRT_TIME VARCHAR2(10) , JOURNEY_HURS VARCHAR2(10) , FLIGHT_DAY1 NUMBER(1) , FLIGHT_DAY2 NUMBER(1) , Member function DAYS_FN(FLIGHT_DAY1 in number) return varchar2 , Pragma restrict_references(DAYS_FN , WNDS) );?
?創建對象類型方法主體
CREATE [OR REPLACE] TYPE BODY <typename> AS MEMBERFUNCTION <methodname> (parameter dataype) RETURN<datatype> IS<PL/SQL_block>;MEMBER PROCEDURE <methodname> (parameter datatype); END;例:
create or replace type body FLIGHT_SCH_TYPE asmember function DAYS_FN(FLIGHT_DAY1 in number) return varchar2isdisp_day varchar2(20) ;begin if flight_day1 = 1 thendisp_day := 'Sunday' ; elsif flight_day1 = 2 thendisp_day := 'Monday' ; elsif flight_day1 = 3 then disp_day := 'Tuesday' ; elsif flight_day1 = 4 then disp_day := 'Wednesday' ; elsif flight_day1 = 5 then disp_day := 'Thursday' ; elsif flight_day1 = 6 then disp_day := 'Friday ' ; elsif flight_day1 = 7 thendisp_day := 'Saturday' ; end if ; return disp_day ;end ; end ;?
后續內容請參考本博客文章 Oracle自定義數據類型 2 (調用對象方法)
?
轉載于:https://www.cnblogs.com/arxive/p/6005846.html
總結
以上是生活随笔為你收集整理的Oracle自定义数据类型 1的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用户数以及psp
- 下一篇: 第六十七篇、OC_UITableView