表 AAA 已有 3 男 2 女,皆為「計算機」系。使用顯式游標查詢這些學生,並將 DEPT 欄位更新為「軟體」。
DECLARE
-- 1. 宣告游標
CURSOR c_cs_students IS
SELECT id, name, dept
FROM aaa
WHERE dept = '計算機'
FOR UPDATE; -- 加鎖,防止併發修改
-- 2. 宣告記錄變數對應游標欄位
v_rec c_cs_students%ROWTYPE;
BEGIN
-- 3. 開啟游標
OPEN c_cs_students;
LOOP
-- 4. 擷取下一筆
FETCH c_cs_students INTO v_rec;
EXIT WHEN c_cs_students%NOTFOUND;
-- 5. 更新當前游標指向的列
UPDATE aaa
SET dept = '軟體'
WHERE CURRENT OF c_cs_students; -- 關鍵:WHERE CURRENT OF
END LOOP;
-- 6. 關閉游標
CLOSE c_cs_students;
COMMIT; -- 明確提交
DBMS_OUTPUT.PUT_LINE('已更新 ' || c_cs_students%ROWCOUNT || ' 筆資料');
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE('錯誤: ' || SQLERRM);
END;
/
FOR UPDATE:宣告游標時加鎖,確保後續 WHERE CURRENT OF 更新的是最新版本。WHERE CURRENT OF cursor_name:直接更新游標當前指向的列,無需再寫 WHERE id = v_rec.id,避免主鍵重複查詢。%ROWTYPE / %NOTFOUND / %ROWCOUNT:游標屬性,減少變數宣告、自動適應結構變更。BEGIN
UPDATE aaa SET dept = '軟體' WHERE dept = '計算機';
DBMS_OUTPUT.PUT_LINE('已更新 ' || SQL%ROWCOUNT || ' 筆');
COMMIT;
EXCEPTION WHEN OTHERS THEN ROLLBACK; RAISE;
END;
/
若無複雜行級邏輯(如發送通知、寫入稽核表),單一 UPDATE 陳述式效能最佳、程式碼最少。顯式游標適合「每列需執行複雜程序邏輯」的情境。
SELECT * FROM aaa WHERE dept = '軟體';
應回傳原 5 筆資料,dept 已變更。