在PL/SQL程式設計中,游標是處理多行查詢結果的核心機制。本文系統梳理隱式與顯式游標的操作差異、%TYPE屬性應用、DML語句整合及游標屬性監控等實戰技巧。
PL/SQL中的SELECT INTO僅支援單行查詢,語法結構如下:
SELECT [DISTINCT|ALL] {*|column[,column,...]}
INTO {variable[,variable,...] | record}
FROM {table|(sub-query)}[alias]
WHERE condition;
關鍵限制:若查詢返回超過一行,必須改用顯式游標;INTO子句變量數量、類型必須與SELECT列表完全對應。
透過%TYPE屬性,變數可自動繼承資料庫欄位或其他變數的資料型別與長度,實現結構變更時的零代碼維護。
-- 繼承資料表欄位型別
v_empno SCOTT.EMP.EMPNO%TYPE;
v_salary EMP.SALARY%TYPE;
-- 繼承變數型別(連鎖傳遞)
DECLARE
v_a NUMBER(5) := 10;
v_b v_a%TYPE := 15;
v_c v_a%TYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE('v_a='||v_a||' v_b='||v_b||' v_c='||v_c);
END;
此機制極大降低結構變更帶來的維護成本,建議所有變數宣告優先採用%TYPE。
INSERT、UPDATE、DELETE、LOCK TABLE在PL/SQL中語法與SQL一致,可直接引用DECLARE區塊宣告的變數。
CREATE OR REPLACE PROCEDURE FIRE_EMPLOYEE (p_empno IN NUMBER) AS
v_ename EMP.ENAME%TYPE;
BEGIN
SELECT ename INTO v_ename FROM emp WHERE empno = p_empno;
INSERT INTO former_emp(empno, ename) VALUES (p_empno, v_ename);
DELETE FROM emp WHERE empno = p_empno;
UPDATE former_emp SET date_deleted = SYSDATE WHERE empno = p_empno;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Employee Number Not Found!');
END;
| 屬性 | 型別 | 說明 |
|---|---|---|
| SQL%FOUND | BOOLEAN | DML影響行數>0或SELECT INTO返回行時為TRUE |
| SQL%NOTFOUND | BOOLEAN | 與%FOUND邏輯互斥 |
| SQL%ROWCOUNT | NUMBER | 受影響行數;SELECT INTO成功為1,失敗為0並拋出NO_DATA_FOUND |
| SQL%ISOPEN | BOOLEAN | 隱式游標執行期間開啟,結束即關閉,永遠為FALSE |
BULK COLLECT與FORALL減少上下文切換PGA_AGGREGATE_TARGET參數熟練掌握游標機制、%TYPE動態綁定、DML異常處理與屬性監控,是編寫健壯高效PL/SQL程式的基石。實務中建議建立程式碼審查清單,強制要求異常處理區塊與游標屬性檢查。