Oracle 遍歷遊標的四種方式(for、fetch、while、BULK COLLECT)

1.情景展現

  Oracle 遍歷遊標的三種方式(for、fetch、while、bulk collect+forall)html

2.問題分析

  咱們能夠把遊標想象成一張表,想要遍歷遊標,就要取到遊標的每行數據,因此問題的關鍵就成了:如何取到行數據?sql

3.解決方案

  方式一:FOR 循環(推薦使用)oracle

  變形一:遍歷顯式遊標測試

/* 若是是在存儲過程外使用顯式遊標,須要使用DECLARE關鍵字 */
DECLARE
  /*建立遊標*/
  CURSOR CUR_FIRST_INDEX IS
    SELECT A.ID        A_ID, --一級指標ID
           A.INDEXNAME A_INDEXNAME --一級指標名稱
      FROM INDEX_A A
     ORDER BY A_ID;
  /*定義遊標變量,該變量的類型爲基於遊標CUR_FIRST_INDEX的行記錄*/
  ROW_CUR_FIRST_INDEX CUR_FIRST_INDEX%ROWTYPE;
/*遊標處理*/
BEGIN
  /*遍歷顯式遊標*/
  --FOR 循環
  FOR ROW_CUR_FIRST_INDEX IN CUR_FIRST_INDEX LOOP
    --循環體
    DBMS_OUTPUT.PUT_LINE('{"ID":"' || ROW_CUR_FIRST_INDEX.A_ID || '","名稱":"' || ROW_CUR_FIRST_INDEX.A_INDEXNAME || '"}');
  END LOOP;
END;  

  執行,輸出結果fetch

  變形二:遍歷隱式遊標(推薦使用)大數據

  關於隱式遊標的補充:20200519spa

  for循環遍歷遊標,其實又能夠分爲兩種方式,一種是顯式遊標的遍歷,另外一種是隱式遊標的遍歷。htm

/* 若是是在存儲過程外使用隱式遊標,若是用不到變量無需聲明DECLARE關鍵字 */
/*遊標處理*/
BEGIN
  /*遍歷隱式遊標*/
  --FOR 循環
  FOR ROW_CUR_FIRST_INDEX IN (SELECT A.ID        A_ID, --一級指標ID
                                     A.INDEXNAME A_INDEXNAME --一級指標名稱
                                FROM INDEX_A A
                               ORDER BY A_ID) LOOP
    --循環體
    DBMS_OUTPUT.PUT_LINE('{"ID":"' || ROW_CUR_FIRST_INDEX.A_ID || '","名稱":"' || ROW_CUR_FIRST_INDEX.A_INDEXNAME || '"}');
  END LOOP;
END;

  隱式遊標相較於顯式遊標用法更加簡單,無需聲明直接調用便可。    blog

  方式二:FETCH 循環開發

/*遊標聲明代碼和方式一一致,此處省略,直接展現遊標處理代碼*/
BEGIN
  /*遍歷遊標*/
  --FETCH 循環
  OPEN CUR_FIRST_INDEX; --必需要明確的打開和關閉遊標
  LOOP
    FETCH CUR_FIRST_INDEX INTO ROW_CUR_FIRST_INDEX;
    EXIT WHEN CUR_FIRST_INDEX%NOTFOUND;
    --循環體
    DBMS_OUTPUT.PUT_LINE('{"ID":"' || ROW_CUR_FIRST_INDEX.A_ID || '","名稱":"' || ROW_CUR_FIRST_INDEX.A_INDEXNAME || '"}');
  END LOOP;
  CLOSE CUR_FIRST_INDEX;
END;

  

  方式三:WHILE 循環

/*遊標聲明代碼和方式一一致,此處省略,直接展現遊標處理代碼*/
BEGIN
  /*遍歷遊標*/
  OPEN CUR_FIRST_INDEX; --必需要明確的打開和關閉遊標 
  FETCH CUR_FIRST_INDEX
    INTO ROW_CUR_FIRST_INDEX;
  WHILE CUR_FIRST_INDEX%FOUND LOOP
    --循環體 
    DBMS_OUTPUT.PUT_LINE('{"ID":"' || ROW_CUR_FIRST_INDEX.A_ID || '","名稱":"' || ROW_CUR_FIRST_INDEX.A_INDEXNAME || '"}');
    FETCH CUR_FIRST_INDEX
      INTO ROW_CUR_FIRST_INDEX;
  END LOOP;
  CLOSE CUR_FIRST_INDEX;
END;  

  注意:使用while循環時,須要fetch兩次。

  方式四:BULK COLLECT+FORALL(速度最快)

/* 若是是在存儲過程外使用顯示遊標,須要使用DECLARE關鍵字 */
/*聲明遊標*/
DECLARE
  /*建立顯式遊標*/
  CURSOR CUR_FIRST_INDEX IS
    SELECT A.ID        A_ID, --一級指標ID
           A.INDEXNAME A_INDEXNAME --一級指標名稱
      FROM INDEX_A A
     ORDER BY A_ID;
  /*定義表類型,該表的表結構爲遊標CUR_FIRST_INDEX的行記錄(能夠存儲多條遊標記錄)*/
  TYPE TABLE_CUR_FIRST_INDEX IS TABLE OF CUR_FIRST_INDEX%ROWTYPE;
  /* 聲明表變量*/
  TAB_FIRST_INDEX TABLE_CUR_FIRST_INDEX;
/*遊標處理過程*/
BEGIN
  /*遍歷遊標*/
  OPEN CUR_FIRST_INDEX;
  LOOP
    --將n行遊標數據放到表中
    FETCH CUR_FIRST_INDEX BULK COLLECT
      INTO TAB_FIRST_INDEX LIMIT 1; -- 數據量太少,僅當前測試使用哦,實際開發建議 500 左右
    -- 退出條件
    EXIT WHEN TAB_FIRST_INDEX.COUNT = 0;
    --循環表數據
    FORALL I IN TAB_FIRST_INDEX.FIRST .. TAB_FIRST_INDEX.LAST LOOP
      DBMS_OUTPUT.PUT_LINE('{"ID":"' || TAB_FIRST_INDEX(I).A_ID || '","名稱":"' || TAB_FIRST_INDEX(I).A_INDEXNAME || '"}');
    END LOOP;
  END LOOP;
  CLOSE CUR_FIRST_INDEX;
END;

    

4.總結 

  使用for循環的優點在於:

  不須要手動打開&關閉遊標(聲明遊標的開啓和關閉);

  不須要手動捕獲數據(自動將數據fetch到記錄型變量);

  不須要關注什麼時候要退出,也就是不須要寫退出循環的知足條件(遍歷完成就會退出)。

  第4方式與前3種的區別在於:

  前三種的遊標變量:ROW_CUR_FIRST_INDEX,只能存儲遊標的一條數據;

  第四種的表變量:TAB_FIRST_INDEX,能夠存儲遊標的多條數據。

  大數據批量處理的時候,第4種方式的優點將會凸顯出來。

寫在最後

  哪位大佬如若發現文章存在紕漏之處或須要補充更多內容,歡迎留言!!!

 相關推薦:

相關文章
相關標籤/搜索