PLSQL中的遊標

遊標是一個私有的SQL工作區域,Oracle數據庫中有兩種遊標,分別是隱式遊標和顯式遊標, 隱式遊標不易被用戶和程序員察覺和意識到,實際上Oracle服務器使用隱式遊標來解析和執行我們提交的SQL 語句; 而顯式遊標是程序員在程序中顯式聲明的;通常我們說的遊標均指顯式遊標。

 

隱式遊標的幾個有用屬性:

SQL%ROWCOUNT 受最近的SQL語句影響的行數

SQL%FOUND 最近的SQL語句是否影響了一行以上的 數據

SQL%NOTFOUND 最近的SQL語句是否未影響任何數據

SQL%ISOPEN 對於隱式遊標而言永遠爲FALSE

例如:

VARIABLE rows_deleted VARCHAR2(30)

DECLARE

v_employee_id employees.employee_id%TYPE := 176;

BEGIN

DELETE FROM employees WHERE

employee_id = v_employee_id;

rows_deleted := (SQL%ROWCOUNT ||' row deleted.');

END;

 

顯式遊標:

1、一行一行的處理返回的數據。

2、保持當前處理行的一個跟蹤,像一個指針一樣指示當前的處理的記錄。

3、允許程序員在PLSQL塊中人爲的控制遊標的開啓、關閉、上下移動;

 

此圖爲顯式遊標標準的語句

 

如果你覺得像前面那個例子那樣對一個遊標的遍歷很麻煩的話,可以考慮使用For循環,For循環省去了遊標的 聲明、打開、提取、測試、關閉等語句,對程序員來說很方便,語法如下:——————兩種方法

DECLARE

CURSOR emp_cursor IS

SELECT employee_id

,last_name

,departments.department_name

FROM employees

,departments

WHERE employees.department_id = departments.department_id

AND employees.department_id = 90

FOR UPDATE OF salary NOWAIT ;

BEGIN

FOR emp_data IN emp_cursor LOOP

UPDATE employees e

SET e.salary = 29999

--where e.employee_id = emp_data.employee_id

WHERE CURRENT OF emp_cursor;

END LOOP;

END;

或者:

BEGIN

FOR emp_record IN (SELECT last_name, department_id

FROM employees) LOOP

-- implicit open and implicit fetch occur

IF emp_record.department_id = 80 THEN

... END LOOP; -- implicit close occurs

END;

遊標可以帶參數:

例如:

DECLARE

CURSOR emp_cursor (p_deptno NUMBER, p_job VARCHAR2) IS

SELECT employee_id, last_name

FROM employees

WHERE department_id = p_deptno

AND job_id = p_job;

BEGIN

OPEN emp_cursor (80, 'SA_REP');

. . .

CLOSE emp_cursor;

OPEN emp_cursor (60, 'IT_PROG');

. . .

END;

FOR UPDATE NOWAIT語句:有的時候我們打開一個遊標是爲了更新或者刪除一些記錄,這種情況下我們希望 在打開遊標的時候即鎖定相關記錄,應該使用for update nowait語句,倘若鎖定失敗我們就停止不再繼續,以免 出現長時間等待資源的死鎖情況。

DECLARE

CURSOR emp_cursor IS

SELECT employee_id, last_name, department_name

FROM employees,departments

WHERE employees.department_id =

departments.department_id

AND employees.department_id = 80

FOR UPDATE OF salary NOWAIT;

WHERE CURRENT OF cursor :

我們經常要逐條處理遊標中的每一條記錄,在循環體內做Update 或者 Delete 時需要有Where指向遊標的當前記錄, 有沒有簡單一點的的Where條件寫法呢?

DECLARE

CURSOR sal_cursor IS

SELECT e.department_id, employee_id, last_name, salary

FROM employees e, departments d

WHERE d.department_id = e.department_id

and d.department_id = 60

FOR UPDATE OF salary NOWAIT;

BEGIN

FOR emp_record IN sal_cursor

LOOP

IF emp_record.salary < 5000 THEN

UPDATE employees

SET salary = emp_record.salary * 1.10

WHERE CURRENT OF sal_cursor;

END IF;

END LOOP;

END;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章