一,引用數據類型
1,%type:單行單字段。
2,%rowtype:單行全部字段。
declare
v_empno emp.empno%TYPE;
v_emp emp%ROWTYPE;
BEGIN
-- %type 單行單個字段
SELECT e.empno INTO v_empno FROM emp e WHERE e.ename = 'YOUNG';
/*以下查詢報錯:ORA-01422:實際返回的行數超出請求行數
--SELECT e.empno INTO v_empno FROM emp e WHERE e.deptno = 10 ; */
dbms_output.put_line('%type:'||v_empno);
-- %rowtype 單行所有字段
SELECT e.* INTO v_emp FROM emp e WHERE e.ename = 'YOUNG';
/*以下查詢報錯:ORA-01422:實際返回的行數超出請求行數
SELECT e.empno INTO v_empno FROM emp e WHERE e.deptno = 10 ; */
dbms_output.put_line('%rowtype:'||v_emp.empno||','||v_emp.ename
||','||v_emp.deptno||','||v_emp.HIREDATE);
END;
二,複合數據類型
(一),record:單行記錄,可以自定義所包含的字段;
TYPE RECORD_NAME IS RECORD(--聲明記錄數據類型
V1 DATA_TYPE1 [NOT NULL][:=DEFAULT_VALUE],--定義變量、變量數據類型
V2 DATA_TYPE2 [NOT NULL][:=DEFAULT_VALUE],
VN DATA_TYPEN [NOT NULL][:=DEFAULT_VALUE]);
declare
-- record 自定義所需的字段
TYPE record_emp IS RECORD(
v_empno emp.empno%TYPE, --引用emp中empno的類型
v_ename emp.ename%TYPE,
v_sal emp.sal%TYPE
);
v_emp_record record_emp;
BEGIN
-- record 單行自定義的字段
-- record select中字段順序與record中定義的順序一致
SELECT e.empno,e.ename,e.sal INTO v_emp_record
FROM emp e WHERE e.ename = 'YOUNG';
dbms_output.put_line('record:'||v_emp_record.v_empno||','||v_emp_record.v_ename
||','||v_emp_record.v_sal);
END;
(二),varray:數組
TYPE varray_type_name IS VARRAY(n) of <element_type>
1,一個VARRAY類型是用TYPE語句創建。必須指定最大長度n,以及元素的數據類element_type。
2,下標從 1 開始算,而不是 0。
3,使用extend申請空間,一次只申請一個空間長度。
4,可以創建一維數組,也可以創建多維數組,這取決於元素類型。
declare
-- record 自定義所需的字段
TYPE record_emp IS RECORD(
v_empno emp.empno%TYPE,
v_ename emp.ename%TYPE,
v_sal emp.sal%TYPE
);
--聲明最大長度爲100,元素類型爲record_emp的多維數組
TYPE emp_array IS VARRAY(100) OF record_emp;
-- 聲明變量
v_emp_array emp_array;
v_emp_record record_emp;
--定義遊標獲取數據
CURSOR cr_emp IS SELECT empno,ename,sal FROM emp;
posit INT :=0; --下標
N_ENTRIES INT;
ARRAY_CAPACITY INT;
BEGIN
--構造方法,進行初始化一個空數組
v_emp_array := emp_array();
-- 添加元素
FOR e IN cr_emp LOOP
posit :=posit+1;
v_emp_array.extend; --在末端添加一個空元素
v_emp_array(posit) := e;
END LOOP;
--數組容量,元素個數
ARRAY_CAPACITY := v_emp_array.LIMIT();
dbms_output.put_line('數組最大容量:'||ARRAY_CAPACITY);
N_ENTRIES := v_emp_array.count();
dbms_output.put_line('數組中元素個數:'||N_ENTRIES);
-- 遍歷數組
--first() 返回第一個元素下標,始終返回1
--last() 返回最後一個元素下標,始終返回count()結果
dbms_output.put_line('first()和last()遍歷數組');
FOR i IN v_emp_array.first() ..v_emp_array.last() LOOP
dbms_output.put_line('員工號:'||v_emp_array(i).v_empno||' 員工名:'||v_emp_array(i).v_ename);
END LOOP;
-- next(x) 返回在第x個元素之後緊挨的元素下標(x+1),若x爲最後一個元素,則返回null
-- prior(x) 返回在第x個元素之前緊挨的元素下標(x-1),若x爲第一個元素,則返回null
dbms_output.put_line('next(x)遍歷數組');
posit := v_emp_array.first();
WHILE posit IS NOT NULL LOOP
dbms_output.put_line('員工號:'||v_emp_array(posit).v_empno||' 員工名:'||v_emp_array(posit).v_ename);
posit :=v_emp_array.next(posit);
END LOOP;
dbms_output.put_line('prior(x)遍歷數組');
posit := v_emp_array.last();
WHILE posit IS NOT NULL LOOP
dbms_output.put_line('員工號:'||v_emp_array(posit).v_empno||' 員工名:'||v_emp_array(posit).v_ename);
posit :=v_emp_array.prior(posit);
END LOOP;
-- 刪除元素
v_emp_array.trim(3); --從末尾開始刪除3個元素,不帶參數則刪除最後一個元素
N_ENTRIES := v_emp_array.count();
dbms_output.put_line('數組中元素個數:'||N_ENTRIES);
v_emp_array.delete(); --刪除所有元素
N_ENTRIES := v_emp_array.count();
dbms_output.put_line('數組中元素個數:'||N_ENTRIES);
END;
(三),table:表
type table_name is table of element_type[not null]
[index by [binary_integer|pls_integer]];
index by : 創建一個主鍵索引,以便引用記錄表變量中的特定行.
-- 下列參數下標自增(無需 顯示初始化:extend)
binary_integer : 由 Oracle來 執行,不會出現溢出,但是執行速度較慢,
因爲它是由 Oracle 模擬執行。
pls_integer : 由硬件即直接由 CPU 來運算,因而會出現溢出,但其執行速度
較前者快許多,一般使用 pls_integer 就可以,除非批次處理業務量大於 21,4748,3647 ,才考慮使用 binary_integer
1,table與varray用法和功能上相似,除了對index by的使用
2,index by是可選的,但是會影響使用。
聲明table時,使用index by
DECLARE
-- record 自定義所需的字段
TYPE record_emp IS RECORD(
v_empno emp.empno%TYPE,
v_ename emp.ename%TYPE,
v_sal emp.sal%TYPE
);
-- 聲明類型爲record_emp的table
TYPE emp_array IS TABLE OF record_emp INDEX BY PLS_INTEGER;
-- 聲明變量
v_emp_array emp_array;
v_emp_record record_emp;
new_emp_record record_emp;
--定義遊標獲取數據
CURSOR cr_emp IS SELECT empno,ename,sal FROM emp WHERE deptno =20;
posit INT :=0;
BEGIN
-- 此時不需要構造函數 進行初始化
-- 添加元素
FOR e IN cr_emp LOOP
v_emp_array(posit) := e;
-- dbms_output.put_line(posit||'員工號:'||v_emp_array(posit).v_empno||' 員工名:'||v_emp_array(posit).v_ename);
posit :=posit+1; -- 下標既可以從0開始,又可以從1開始
END LOOP;
-- 新增元素時,直接插入
SELECT '1111','new',9999 INTO new_emp_record FROM dual;
v_emp_array(v_emp_array.last+1) := new_emp_record;
-- 遍歷數組
--first() 返回第一個元素下標,始終返回1
--last() 返回最後一個元素下標,始終返回count()結果
dbms_output.put_line('first()和last()遍歷數組');
FOR i IN v_emp_array.first ..v_emp_array.last() LOOP
dbms_output.put_line(i||'員工號:'||v_emp_array(i).v_empno||' 員工名:'||v_emp_array(i).v_ename);
END LOOP;
聲明table時,不使用index by
**DECLARE
-- record 自定義所需的字段
TYPE record_emp IS RECORD(
v_empno emp.empno%TYPE,
v_ename emp.ename%TYPE,
v_sal emp.sal%TYPE
);
-- 聲明類型爲record_emp的table
TYPE emp_array IS TABLE OF record_emp ;
-- 聲明變量
v_emp_array emp_array;
v_emp_record record_emp;
new_emp_record record_emp;
--定義遊標獲取數據
CURSOR cr_emp IS SELECT empno,ename,sal FROM emp WHERE deptno =20;
posit INT :=0;
BEGIN
-- 此時需要構造函數 進行初始化
v_emp_array := emp_array();
-- 添加元素
FOR e IN cr_emp LOOP
posit :=posit+1; --下標需要從1開始
v_emp_array.extend; --在末端添加一個空元素
v_emp_array(posit) := e;
END LOOP;
--新增元素是需要使用extend()在末尾增加一個空元素,再賦值
SELECT '1111','new',9999 INTO new_emp_record FROM dual;
v_emp_array.extend();
v_emp_array(v_emp_array.last) := new_emp_record;
-- 遍歷數組
--first() 返回第一個元素下標,始終返回1
--last() 返回最後一個元素下標,始終返回count()結果
dbms_output.put_line('first()和last()遍歷數組');
FOR i IN v_emp_array.first ..v_emp_array.last() LOOP
dbms_output.put_line(i||'員工號:'||v_emp_array(i).v_empno||' 員工名:'||v_emp_array(i).v_ename);
END LOOP;
END;**
有無index by的區別在於
1,使用table前是否需要進行初始化,帶index by不用初始化,不帶則需要。
2,索引能否從0開始,帶index by的既可以從0開始,又可以從1開始,不帶則必須從1開始,這與varray一樣。
3,新增元素時是否需要收到申請空間,帶index by可以在末尾直接添加,不帶則需要用extend()申請,再進行添加,這與varray一樣。
參考:
https://blog.csdn.net/qq_34745941/article/details/81368648
數據來源:使用scott用戶的emp表
若有錯誤,可以評論拍磚!!!