游標FOR循環(huán)
在大多數時(shí)候我們在設計程序的時(shí)候都遵循下面的步驟:
1、打開(kāi)游標
2、開(kāi)始循環(huán)
3、從游標中取值
4、檢查那一行被返回
5、處理
6、關(guān)閉循環(huán)
7、關(guān)閉游標
可以簡(jiǎn)單的把這一類(lèi)代碼稱(chēng)為游標用于循環(huán)。但還有一種循環(huán)與這種類(lèi)型不相同,這就是FOR循環(huán),用于FOR循環(huán)的游標按照正常的聲明方式聲明,它的優(yōu)點(diǎn)在于不需要顯式的打開(kāi)、關(guān)閉、取數據,測試數據的存在、定義存放數據的變量等等。游標FOR循環(huán)的語(yǔ)法如下:
FOR record_name IN
(corsor_name[(parameter[,parameter]...)]
| (query_difinition)
LOOP
statements
END LOOP;
下面我們用for循環(huán)重寫(xiě)上面的例子:
DECALRE
CURSOR c_dept IS SELECTdeptno,dname FROM dept ORDER BY deptno;
CURSOR c_emp (p_deptVARACHAR2) 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_deptLOOP
DBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname);
v_tot_salary:=0;
FOR r_emp INc_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;
在游標FOR循環(huán)中使用查詢(xún)
在游標FOR循環(huán)中可以定義查詢(xún),由于沒(méi)有顯式聲明所以游標沒(méi)有名字,記錄名通過(guò)游標查詢(xún)來(lái)定義。
DECALRE
v_tot_salaryEMP.SALARY%TYPE;
BEGIN
FOR r_dept IN (SELECTdeptno,dname FROM dept ORDER BY deptno) LOOP
DBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname);
v_tot_salary:=0;
FOR r_emp IN(SELECT ename,salary
FROM emp
WHERE deptno=p_dept
ORDER BY ename) 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('ToltalSalary for dept:'|| v_tot_salary);
END LOOP;
END;
游標中的子查詢(xún)
語(yǔ)法如下:
CURSOR C1 IS SELECT * FROMemp
WHERE deptno NOT IN (SELECTdeptno
FROM dept
WHEREdname!='ACCOUNTING');
可以看出與SQL中的子查詢(xún)沒(méi)有什么區別。
游標中的更新和刪除
在PL/SQL中依然可以使用UPDATE和DELETE語(yǔ)句更新或刪除數據行。顯式游標只有在需要獲得多行數據的情況下使用。PL/SQL提供了僅僅使用游標就可以執行刪除或更新記錄的方法。
UPDATE或DELETE語(yǔ)句中的WHERE CURRENTOF子串專(zhuān)門(mén)處理要執行UPDATE或DELETE操作的表中取出的最近的數據。要使用這個(gè)方法,在聲明游標時(shí)必須使用FORUPDATE子串,當對話(huà)使用FORUPDATE子串打開(kāi)一個(gè)游標時(shí),所有返回集中的數據行都將處于行級(ROW-LEVEL)獨占式鎖定,其他對象只能查詢(xún)這些數據行,不能進(jìn)行UPDATE、DELETE或SELECT...FOR UPDATE操作。
語(yǔ)法:
FOR UPDATE [OF[schema.]table.column[,[schema.]table.column]..
[nowait]
在多表查詢(xún)中,使用OF子句來(lái)鎖定特定的表,如果忽略了OF子句,那么所有表中選擇的數據行都將被鎖定。如果這些數據行已經(jīng)被其他會(huì )話(huà)鎖定,那么正常情況下Oracle將等待,直到數據行解鎖。
在UPDATE和DELETE中使用WHERE CURRENTOF子串的語(yǔ)法如下:
WHERE{CURRENT OFcursor_name|search_condition}
例:
DELCARE
CURSOR c1 IS SELECTempno,salary
FROM emp
WHERE comm IS NULL
FOR UPDATE OF comm;
v_comm NUMBER(10,2);
BEGIN
FOR r1 IN c1 LOOP
IF r1.salary<500THEN
v_comm:=r1.salary*0.25;
ELSEIFr1.salary<1000 THEN
v_comm:=r1.salary*0.20;
ELSEIFr1.salary<3000 THEN
v_comm:=r1.salary*0.15;
ELSE
v_comm:=r1.salary*0.12;
END IF;
UPDATE emp;
SET comm=v_comm
WHERE CURRENT OFc1l;
END LOOP;
END