記錄變數
定義一個記錄變數使用TYPE命令和%ROWTYPE,關於%ROWsTYPE的更多資訊請參閱相關資料。記錄變數用於從遊標中提取資料行,當遊標選擇很多列的時候,那麼使用記錄比為每列聲明一個變數要方便得多。當在表上使用%ROWTYPE並將從遊標中取出的值放入記錄中時,如果要選擇表中所有列,那麼在SELECT子句中使用*比將所有列名列出來要安全得多。
例:
SET SERVERIUTPUT ON
DECLARE
R_emp EMP%ROWTYPE;
CURSOR c_emp IS SELECT * FROM emp;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO r_emp;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUT.PUT.PUT_LINE('Salary of Employee'||r_emp.ename||'is'|| r_emp.salary);
END LOOP;
CLOSE c_emp;
END;
%ROWTYPE也可以用遊標名來定義,這樣的話就必須要首先聲明遊標:
SET SERVERIUTPUT ON
DECLARE
CURSOR c_emp IS SELECT ename,salary FROM emp;
R_emp c_emp%ROWTYPE;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO r_emp;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUT.PUT.PUT_LINE('Salary of Employee'||r_emp.ename||'is'|| r_emp.salary);
END LOOP;
CLOSE c_emp;
END;
帶參數的遊標
與預存程序和函數相似,可以將參數傳遞給遊標並在查詢中使用。這對於處理在某種條件下開啟遊標的情況非常有用。它的文法如下:
CURSOR cursor_name[(parameter[,parameter],...)] IS select_statement;
定義參數的文法如下:
Parameter_name [IN] data_type[{:=|DEFAULT} value]
與預存程序不同的是,遊標只能接受傳遞的值,而不能傳回值。參數只定義資料類型,沒有大小。
另外可以給參數設定一個預設值,當沒有參數值傳遞給遊標時,就使用預設值。遊標中定義的參數只是一個預留位置,在別處引用該參數不一定可靠。
在開啟遊標時給參數賦值,文法如下:
OPEN cursor_name[value[,value]....];
參數值可以是文字或變數。
例:
DECALRE
CURSOR c_dept IS SELECT * FROM dept ORDER BY deptno;
CURSOR c_emp (p_dept VARACHAR2) IS
SELECT ename,salary
FROM emp
WHERE deptno=p_dept
ORDER BY ename
r_dept DEPT%ROWTYPE;
v_ename EMP.ENAME%TYPE;
v_salary EMP.SALARY%TYPE;
v_tot_salary EMP.SALARY%TYPE;
BEGIN
OPEN c_dept;
LOOP
FETCH c_dept INTO r_dept;
EXIT WHEN c_dept%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname);
v_tot_salary:=0;
OPEN c_emp(r_dept.deptno);
LOOP
FETCH c_emp INTO v_ename,v_salary;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Name:'|| v_ename||' salary:'||v_salary);
v_tot_salary:=v_tot_salary+v_salary;
END LOOP;
CLOSE c_emp;
DBMS_OUTPUT.PUT_LINE('Toltal Salary for dept:'|| v_tot_salary);
END LOOP;
CLOSE c_dept;
END;
遊標FOR迴圈
在大多數時候我們在設計程式的時候都遵循下面的步驟:
1、開啟遊標
2、開始迴圈
3、從遊標中取值
4、檢查那一行被返回
5、處理
6、關閉迴圈
7、關閉遊標
可以簡單的把這一類代碼稱為遊標用於迴圈。但還有一種迴圈與這種類型不相同,這就是FOR迴圈,用於FOR迴圈的遊標按照正常的聲明方式聲明,它的優點在於不需要顯式的開啟、關閉、取資料,測試資料的存在、定義存放資料的變數等等。遊標FOR迴圈的文法如下:
FOR record_name IN
(corsor_name[(parameter[,parameter]...)]
| (query_difinition)
LOOP
statements
END LOOP;
下面我們用for迴圈重寫上面的例子:
DECALRE
CURSOR c_dept IS SELECT deptno,dname FROM dept ORDER BY deptno;
CURSOR c_emp (p_dept VARACHAR2) IS
SELECT ename,salary
FROM emp
WHERE deptno=p_dept
ORDER BY ename
v_tot_salary EMP.SALARY%TYPE;
BEGIN
FOR r_dept IN c_dept LOOP
DBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname);
v_tot_salary:=0;
FOR r_emp IN c_emp(r_dept.deptno) LOOP
DBMS_OUTPUT.PUT_LINE('Name:' || v_ename || 'salary:' || v_salary);
v_tot_salary:=v_tot_salary+v_salary;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Toltal Salary for dept:'|| v_tot_salary);
END LOOP;
END;