Oracle提供自訂類型功能,使用者可以根據自己的情況定義記錄資料類型(Record)和記錄表類型(Table),其中記錄資料類型Record儲存是一條記錄,記錄表類型Table用來儲存多條記錄。如果記錄資料類型Record是一維數組的話,記錄表類型Table就是二維數組。
自訂類型有兩種寫法:TYPE...IS和CREATE TYPE,兩種定義方式的區別是:前者一般在預存程序和函數中定義,使用範圍也限於所在過程或函數,而後者方式聲明物件類型,物件類型則是作為一個方案對象(像表、索引、視圖、觸發器一樣,是一個方案對象),可以過程或函數中使用,還可以在定義表時,作為欄位的類型。
下面分別介紹:
TYPE IS定義類型
1. 定義資料記錄類型
文法:
TYPE type_name IS RECORD (
欄位1 類型1,
欄位2 類型2,
...
欄位n 類型n
);
說明:
1) type_name:類型名稱。
舉例:
declare
TYPE type_student IS RECORD(
name VARCHAR2(100),
age NUMBER(3),
sex VARCHAR2(1)
);
r_student type_student;
v_name VARCHAR2(100);
i_age NUMBER(3);
v_sex VARCHAR(1);
i integer;
begin
select name, age, sex into r_student from t_student where gid = 1;
v_name := r_student.name;
i_age := r_student.age;
v_sex := r_student.sex;
dbms_output.put_line(v_name);
dbms_output.put_line(v_sex);
dbms_output.put_line(i_age);
end;
輸出結果:
zhansan
1
12
2.定義表記錄
文法:
TYPE type_name IS TABLE OF element_type
INDEX BY [BINARY_INTEGER | PLS_INTEGER | VARRAY2];
說明:
1) type_name:類型名稱。
2) element_type:可以是基本類型(如varchar2, Ingeger, number等)、記錄資料類型(即TYPEtype_nameIS RECORD定義的類型)、%ROWTYPE。
3) INDEX BY:該語句的作用是使Number類型的下標自增長,自動初始化,並分配空間,有了該語句,向表記錄插入元素
時,不需要顯示初始化,也不需要通過extend分配空間。Binary_Integer 與 Pls_Integer 都是整數型別.
Binary_Integer類型變數值計算是由Oracle來執行,不會出現溢出,但是執行速度較慢,因為它是由Oracle
類比執行。而Pls_Integer的執行是由硬體即直接由CPU來運算,因而會出現溢出,但其執行速度較前者快許多。
如果沒有使用這個語句,又沒有使用extend就會報錯:ORA-06531:Reference to uninitialized
collection,具體請參考《ORA-06531:Reference to uninitialized collection 問題解決》
舉例:
declare
TYPE type_student IS RECORD(
name VARCHAR2(100),
age NUMBER(3),
sex VARCHAR2(1)
);
TYPE t_student_var IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
TYPE t_student_rec IS TABLE OF type_student INDEX BY BINARY_INTEGER;
TYPE t_student_rowtype IS TABLE OF t_student%ROWTYPE INDEX BY BINARY_INTEGER;
v_tbl_name t_student_var;
v_tbl_record t_student_rec;
v_tbl_rowtype t_student_rowtype;
begin
dbms_output.put_line('------------基本類型VARCHAR2表記錄------------');
select name into v_tbl_name(1) from t_student where gid = 1;
select name into v_tbl_name(2) from t_student where gid = 2;
select name into v_tbl_name(3) from t_student where gid = 3;
dbms_output.put_line(v_tbl_name(1));
dbms_output.put_line(v_tbl_name(2));
dbms_output.put_line(v_tbl_name(3));
dbms_output.put_line('------------自訂RECORD類型表記錄------------');
select name, age, sex into v_tbl_record(1) from t_student where gid = 1;
select name, age, sex into v_tbl_record(2) from t_student where gid = 2;
select name, age, sex into v_tbl_record(3) from t_student where gid = 3;
dbms_output.put_line('name:'||v_tbl_record(1).name||', '||'age:'||v_tbl_record(1).age||', '||'sex:'||v_tbl_record(1).sex);
dbms_output.put_line('name:'||v_tbl_record(2).name||', '||'age:'||v_tbl_record(2).age||', '||'sex:'||v_tbl_record(2).sex);
dbms_output.put_line('name:'||v_tbl_record(3).name||', '||'age:'||v_tbl_record(3).age||', '||'sex:'||v_tbl_record(3).sex);
dbms_output.put_line('------------表記錄類型表記錄------------');
select * into v_tbl_rowtype(1) from t_student where gid = 1;
select * into v_tbl_rowtype(2) from t_student where gid = 2;
select * into v_tbl_rowtype(3) from t_student where gid = 3;
dbms_output.put_line('name:'||v_tbl_rowtype(1).name||', '||'age:'||v_tbl_rowtype(1).age||', '||'sex:'||v_tbl_rowtype(1).sex||', '||'grade:'||v_tbl_rowtype(1).grade);
dbms_output.put_line('name:'||v_tbl_rowtype(2).name||', '||'age:'||v_tbl_rowtype(2).age||', '||'sex:'||v_tbl_rowtype(2).sex||', '||'grade:'||v_tbl_rowtype(2).grade);
dbms_output.put_line('name:'||v_tbl_rowtype(3).name||', '||'age:'||v_tbl_rowtype(3).age||', '||'sex:'||v_tbl_rowtype(3).sex||', '||'grade:'||v_tbl_rowtype(3).grade);
end;
輸出結果:
------------基本類型VARCHAR2表記錄------------
zhansan
lisi
wanwu
------------自訂RECORD類型表記錄------------
name:zhansan, age:12, sex:1
name:lisi, age:23, sex:1
name:wanwu, age:32, sex:1
------------表記錄類型表記錄------------------
name:zhansan, age:12, sex:1, grade:643
name:lisi, age:23, sex:1, grade:445
name:wanwu, age:32, sex:1, grade:545