目錄
複合數據類型
複數據類型包括:
- 記錄
- 關聯數組(index by表)
- 嵌套表
- 可變長度數組
PL/SQL 記錄
和C++中的結構體比較像。
它是有幾個相關值構 成的複合變量,是表中單行數據結構的一個鏡像,可用於支持SELECT語句的返回值。記錄 將一行數據看成一個單元,而不是將每一列單獨處理
定義
TYPE record_type IS RECORD
(
Variable_1 datatype1[,
Variable_2 datatype2[, ...]]
);
注意這樣定義的是類型,還要再定義這個類型的變量。
例:
DECLARE
TYPE NewRecordTYPE IS RECORD
(
id number,
name varchar2(10)
);
recTest NEWRECORDTYPE;
BEGIN
SELECT empno,ename INTO recTest
FROM emp WHERE empno=7369;
DBMS_OUTPUT.PUT_LINE
(recTest.id||'號員工的姓名是'||recTest.name);
END;
%ROWTYPE屬性
聲明的變量對應於數據庫表或視圖中列的集合。在%ROWTYPE之前加上數據庫表名。字段表示表中的列。
這種數據類型可以一個變量把整個表的東西讀出來,用".元素名"使用。
DECLEAR
emp_rec emp%rowtype;
BEGIN
select * into emp_rec
from emp
where empno=7788;
INSERT INTO test VALUES
(emp_rec.EMPNO,emp_rec.ENAME,...,)
commit;
END;
遊標
遊標是一種PL/SQL控制結構,可以對SQL語句 的處理進行顯式控制,便於對遊標的行數據逐條進行處理。
分爲隱式遊標和顯式遊標。
例如刪除數據時刪除掉多少行數據,就通過隱式遊標來獲得。
隱式遊標
從EMP中刪除指定部門,返回刪除的行的數量。
DECLARE
v_deptno NUMBER := 20;
v_rows_deleted VARCHAR2(30);
BEGIN
DELETE FROM emp
WHERE deptno = v_deptno;
v_rows_deleted := SQL%ROWCOUNT;
dbms_output.put_line(v_rows_deleteed || 'rows deleted.');
END;
顯示遊標
需要自己定義打開顯示關閉。
理解:遊標存在指針,從剛開始指向第一條,逐漸移動來遍歷結果集。
操作:
- 定義遊標
- 打開遊標
- 提取遊標
- 關閉遊標
注意:一點特殊的是,遍歷到的結果集不能再取了,即只能順着遍歷,不能倒回來看。
聲明
CURSOR cur_name IS
select statement
打開遊標
OPEN cur_name
提取遊標
FETCH cur_name INTO [variable1,variable2,...]
關閉遊標
關閉遊標釋放佔用的內存空間,不寫也是不出問題的。
CLOSE cur_name
例子:
DECLARE
v_ename emp.name%TYPE;
v_sal emp.sal%TYPE;
CURSOR cur_emp IS
select ename,sal
from emp
where sal>2000;
BEGIN
OPEN cur_emp;
FETCH cur_emp INTO v_ename,v_sal;
dbms_output.putline(v_ename || ' ' || v_sal);
FETCH cur_emp INTO v_ename,v_sal;
dbms_output.put_line(v_ename || ' ' || v_sal;
CLOSE cur_emp;
END;
顯示遊標的屬性
屬性 | 類型 | 描述 |
%ISOPEN | bool | 遊標打開的爲TRUE |
%NOTFOUND | bool | FETCH語句沒有返回數據是TRUE |
%FOUND | bool | FETCH返回一行記錄則爲TRUE |
%ROWCOUNT | 數值 | 返回到現在爲止從遊標中取出的記錄數目 |
例子
DECLARE
v_ename emp.name%TYPE;
v_sal emp.sal%TYPE;
CURSOR cur_emp IS
select ename,sal
from emp
where sal>2000;
BEGIN
IF NOT cur_emp%ISOPEN THEN
OPEN cur_emp;
END IF;
LOOP
FETCH cur_emp INTO v_ename,v_sal;
EXIT WHEN cur_emp%NOTFOUND;
dbms_output.putline(cur_emp%ROWCOUNT);
dbms_output.put_line(v_ename || ' ' || v_sal);
END LOOP;
CLOSE cur_emp;
END;
遊標和for循環
- 遊標式的for循環可以方便的處理顯示遊標。
- 隱式的打開提取和關閉遊標。
- 隱式聲明記錄類型變量。
DECLARE
CURSOR emp_cursor IS
SELECT empno,ename FROM emp;
BEGIN
FOR emp_record IN emp_cursor LOOP
dbms_opyput.putline(emp_record.empno);
END LOOP;
END;
帶參數的遊標
每次傳入不同值可以獲得不同的結果集。更靈活
DECLARE
CURSOR cur_emp (p_sal NUMBER) IS
select ename,sal
from emp
where sal>2000;
BEGIN
FOR rec_emp IN cur_emp(2000) LOOP
dbms_output.put_line(v_ename || ' ' || v_sal);
END LOOP;
END;
簡單循環
DECLARE
CURSOR cur_emp (p_sal NUMBER) IS
select ename,sal
from emp
where sal>2000;
rec_emp cur_emp%ROWTYPE
BEGIN
OPEN cur_emp(3000);
LOOP
FETCH cur_emp INTO rec_emp;
EXIT when cur_emp%NOTFOUND;
dbms_output.put_line(v_ename || ' ' || v_sal);
END LOOP;
CLOSE cur_emp;
END;
FOR UPDATE 子句
用遊標對結果集進行修改。期間需要加鎖以拒絕訪問。
語法
SELECT ...
FROM ...
FOR UPDATE [OF column_reference][NOWAIT];
noway表示其他請求無需等待,直接返回錯誤。
SELECT *
FROM emp
WHERE empno=7788
FOR UPDATE nowait;