首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle FOR IN LOOP 兩大經典應用模式:數字範圍迴圈與游標隱性迴圈實戰範例

     編輯:Oracle 資料庫基礎

Oracle PL/SQL 迴圈兩大核心模式:數字範圍與查詢結果集迴圈

FOR ... IN ... LOOP 是 PL/SQL 最常用的迴圈結構。本文展示兩種經典應用:數字範圍迴圈 批次產生日期資料、游標隱性迴圈 動態建表腳本生成,並說明變數作用域、隱性游標優勢與清理最佳實踐。

模式一:數字範圍迴圈 - 批次產生連續日期


-- 1. 建立測試表
CREATE TABLE ETL_DATE (
    DATE_CHAR VARCHAR2(8),
    DATE_DATE DATE
);

-- 2. FOR 迴圈插入 2009/10/01 ~ 2009/10/21
DECLARE
  V_DATE DATE;
BEGIN
  EXECUTE IMMEDIATE 'TRUNCATE TABLE ETL_DATE';
  
  -- 注意:此處 20091001 是數字字面值,非日期
  -- 迴圈變數 V_DATE 隱性宣告為 NUMBER,每次遞增 1
  FOR V_DATE IN 20091001 .. 20091021 LOOP
    INSERT INTO ETL_DATE (DATE_CHAR, DATE_DATE)
    VALUES (TO_CHAR(V_DATE), TO_DATE(TO_CHAR(V_DATE), 'YYYYMMDD'));
  END LOOP;
  
  COMMIT;
END;
/

-- 3. 驗證
SELECT * FROM ETL_DATE ORDER BY DATE_DATE;

-- 4. 清理
DROP TABLE ETL_DATE;

關鍵限制:此寫法僅適用於同一月份內 (如 1001~1031),跨月會產生 1032、1033 等無效日期。跨月請改用 WHILE + DATE + 1 邏輯。

模式二:游標隱性迴圈 - 動態生建表腳本


-- 1. 建立輔助表
CREATE TABLE SQLTEXT (TEXT VARCHAR2(100));
CREATE TABLE HZ (HZ_NAME VARCHAR2(3));
INSERT INTO HZ VALUES ('');
INSERT INTO HZ VALUES ('PRE');
INSERT INTO HZ VALUES ('CUR');
INSERT INTO HZ VALUES ('INS');
INSERT INTO HZ VALUES ('UPD');

-- 2. FOR 迴圈隱性游標遍歷 HZ 表,動態生成建表 SQL
DECLARE
  P_TABLE_NAME VARCHAR2(100) := 'CFA';
BEGIN
  -- 隱性游標:FOR 變數 IN (SELECT ...) LOOP
  FOR HZ_REC IN (SELECT HZ_NAME FROM HZ) LOOP
    INSERT INTO SQLTEXT
    SELECT 'CREATE TABLE ' || REPLACE(P_TABLE_NAME, 'EDW', 'TMP') || 
           HZ_REC.HZ_NAME || ' AS SELECT * FROM ' || P_TABLE_NAME || 
           ' WHERE ROWNUM < 1'
    FROM DUAL;
  END LOOP;
END;
/

-- 3. 驗證生成的 SQL
SELECT * FROM SQLTEXT;
-- 輸出範例:
-- CREATE TABLE CFA AS SELECT * FROM CFA WHERE ROWNUM < 1
-- CREATE TABLE CFAPRE AS SELECT * FROM CFA WHERE ROWNUM < 1
-- CREATE TABLE CFACUR AS SELECT * FROM CFA WHERE ROWNUM < 1
-- ...

-- 4. 清理
DROP TABLE SQLTEXT;
DROP TABLE HZ;

FOR 迴圈 vs 顯性游標對比

特性FOR 迴圈 (隱性游標)顯性游標 (OPEN/FETCH/CLOSE)
程式碼行數少 (自動 OPEN/FETCH/CLOSE)多
變數宣告隱性 (Record 型別自動推導)需手動宣告 Record/變數
異常處理自動 CLOSE需在 EXCEPTION 中手動 CLOSE
參數化查詢不支援 (查詢固定)支援 OPEN cur FOR ... USING ...
動態 SQL不支援支援 OPEN cur FOR dynamic_sql
效能相同 (內部相同機制)相同

最佳實踐建議

  1. 優先使用 FOR 迴圈:簡潔、安全 (自動關閉)、可讀性高
  2. 需要動態 SQL/參數綁定:改用顯性游標 OPEN ... FOR ... USING
  3. 大量資料批次處理:考慮 BULK COLLECT ... LIMIT + FORALL 減少 Context Switch
  4. 迴圈變數作用域:僅在 LOOP 區塊內可見,外部不可存取,避免汙染
  5. 避免在迴圈中 COMMIT:批次處理應在迴圈外統一 COMMIT,或使用 Savepoint

進階:反向迴圈與 STEP 控制


-- 反向迴圈 (10 遞減到 1)
FOR I IN REVERSE 1 .. 10 LOOP
  DBMS_OUTPUT.PUT_LINE(I);
END LOOP;

-- PL/SQL 無 STEP 子句,需用 WHILE 模擬步長
I := 1;
WHILE I <= 10 LOOP
  DBMS_OUTPUT.PUT_LINE(I);
  I := I + 2; -- 步長 2
END LOOP;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved