PL/SQL中複合數據類型與遊標
一.複合數據類型
1.定義:
複合變量類型不是數據庫中已經存在的數據類型,因此複合變量在聲明類型之前,首先要創建複合類型,複合類型創建後可以多次被使用。
2.複合數據類型包括:
--記錄:
存儲在多個字段中的一組相關的數據項,每個字段都有自己的名字和數據類型。
把字段的集合當做一個整體的邏輯單元。
主要用於從表中取出查詢到的行數據。
DECLARE
TYPE emp_record_type IS RECORD --創建一個記錄類型
(ename emp.ename%TYPE,
sal emp.sal%TYPE,
job VARCHAR2(9));
emp_record emp_record_type; --聲明一個記錄類型的變量emp_record
BEGIN
SELECT ename,sal,job
INTO emp_record
FROM emp
WHERE empno = 7788;
dbms_output.put_line('僱員名:='||emp_record.ename||';薪水='||emp_record.sal);
END;
--表
--嵌套表
--數組
3.%ROWTYPE屬性
聲明的變量對應於數據庫表或視圖中列的集合
在%ROWTYPE之前加上數據庫表名
記錄內字段的名字和數據類型參照表或視圖中的列
優點:
可以不必知道數據庫中列的數量和類型。
在運行期間,數據庫中列的數量和類型可能發生變化。
在select語句中使用該屬性可以有效的檢索表中的列。
DECLARE
emp_rec emp%ROWTYPE;
BEGIN
SELECT * INTO emp_rec
FROM emp
WHERE empno=7739;
INSERT INTO test
VALUES(emp_rec.empno,emp_rec.ename,emp_rec.job,emp_rec.mgr,emp_rec.hiredate,emp_rec.sal,emp_rec.comm.emp_rec.deptno);
COMMIT;
END;
二.遊標
1.定義:遊標是Oracle系統在內存中開闢的一個工作區,在其中存放select語句返回的查詢結果。
2.分類:
隱式遊標:PL/SQL隱式建立並自動管理這一遊標。
--由Oracle在內部聲明
--由Oracle自動管理遊標
--可以使用遊標屬性從最近執行的SQL語句中獲取信息
--用於處理DML語句以及返回單行的查詢
屬性:
例子:
DECLARE
v_deptno NUMBER:=21;
rows_deleted VARCHAR2(30);
BEGIN
DELETE FROM emp
WHERE deptno = v_deptno;
rows_deleted:=(SQL%ROWCOUNT||'rows deleted');
dbms_output.put_line(rows_deleted);
END;
顯示遊標:由程序員顯示說明及控制,用於從表中取出多行數據,並將多行數據一行一行單獨處理。
--使用遊標時,select語句查詢的結果可以是單條記錄,多條記錄,也可以是零條記錄。
--在遊標工作區中,存在一個指針,初始狀態它指向查詢結果的首記錄。
--要訪問想查詢結果的所有記錄,可以通過fetch語句,進行指針的移動來實現。
--使用遊標進行操作,包括定義遊標,打開遊標,提取遊標,關閉遊標。
--遊標聲明時,select子查詢不能使用into語句。
屬性:
例子1:
DECLARE
v_empno NUMBER(5);
v_ename VARCHAR2(30);
CURSOR emp_cursor IS
SELECT empno,ename FROM emp;
BEGIN
OPEN emp_cursor;
FOR i IN 1..5 LOOP
FETCH emp_cursor INTO v_empno,v_ename;
dbms_output.put_line(v_empno||' '||v_ename);
END LOOP;
CLOSE emp_cursor;
END;
例子2:
DECLARE
v_empno NUMBER(5);
v_ename VARCHAR2(40);
CURSOR emp_cursor IS
SELECT empno,ename FROM emp;
BEGIN
IF NOT emp_cursor%ISOPEN THEN
OPEN emp_cursor;
END IF;
LOOP
FETCH emp_cursor INTO v_empno,v_ename;
EXIT WHEN emp_cursor%NOTFOUND;
dbms_output.put_line(v_empno||' '||v_ename);
END LOOP;
dbms_output.put_line(emp_cursor%ROWCOUNT);
CLOSE emp_cursor;
END;
3.遊標式For循環
--隱式的打開,提取和關閉遊標
--隱式聲明記錄類型變量
DECLARE
CURSOR EMP_CURSOR IS
SELECT EMPNO, ENAME FROM EMP;
BEGIN
FOR EMP_RECORD IN EMP_CURSOR LOOP
IF EMP_RECORD.ENAME = 'scott' THEN
DBMS_OUTPUT.PUT_LINE(EMP_RECORD.EMPNO);
END IF;
END LOOP;
END;
4.使用子查詢的遊標式For循環(不需聲明遊標)
BEGIN
FOR EMP_RECORD IN (SELECT EMPNO, ENAME FROM EMP) LOOP
IF EMP_RECORD.ENAME = 'scott' THEN
DBMS_OUTPUT.PUT_LINE(EMP_RECORD.EMPNO);
END IF;
END LOOP;
END;
5.帶有參數的遊標
--在遊標處於打開狀態時,執行查詢語句,將參數的值傳遞給遊標。
--多次打開顯示變量,每次活動集都不同。
DECLARE
CURSOR emp_cursor
(p_deptno NUMBER,p_sal NUMBER)
IS
SELECT ename FROM emp
WHERE deptno=p_deptno AND sal>p_sal;
BEGIN
OPEN emp_cursor(10,2000);
CLOSE emp_cursor;
...
OPEN emp_cursor(20,4000);
CLOSE emp_cursor;
...
END;
6.FOR UPDATE子句
--在事務執行期間可以顯示鎖定以拒絕訪問
--在更新或刪除行時要鎖定該行
7.WHERE CURRENT OF子句
--首先要在遊標中使用FOR UPDATE子句鎖定行
--使用WHERE CURRENT OF 子句從顯式遊標中引用當前行