存儲過程關於LOOP循環問題 存儲過程關於LOOP循環問題

存儲過程關於LOOP循環問題

 

本隨筆文章,由個人博客(鳥不拉屎)轉移至博客園
發佈時間: 2018 年 10 月 17 日
原地址:https://niaobulashi.com/archives/procedures_loop.html


存儲過程LOOP疑問

今天在開發需求時,需要編寫一個存儲過程,實現數據的初始化功能。

發現遇到循環處理時,跳出循環的條件,Loop的處理

LOOP EXIT WHRN(P1 > P2);
    ...
END LOOP;

emmmmmm,因爲之前沒有怎麼學習存儲過程,只是看了一下存儲過程的原理,就上手開發了(所謂了敏捷開發哈哈哈哈哈哈)

就引起我的疑問:是直接進入循環呢?還是先判斷條件?

我上網查閱資料。。。好像沒有查閱到額

不過看到有一個類型的,我貼出來

loop
    v_sal := v_sal + 1;
    dbms_output.put_line(v_sal);
    exit when v_sal = 8000;
end loop

這個類比Java的do-while形式是一樣的:先進入循環,滿足條件了跳出循環

我就猜測

第一種也是這種類型的

於是我寫了個測試例子,存儲過程代碼如下:

CREATE OR REPLACE PROCEDURE P_TEST(v_res OUT NUMBER,
                                   v_errorCode  OUT NVARCHAR2,
                                   v_errorMsg   OUT NVARCHAR2,
                                   c_startDate  IN NVARCHAR2) IS

c_firstMonthDay NVARCHAR2(10);     -- 所在月的第一天
c_firstClearDate NVARCHAR2(10);    -- 第一次生成的披露日期
c_clearDate NVARCHAR2(10);         -- 披露日期
c_N NUMBER(10):=1;                 -- 計算使用的倍數,從0開始


BEGIN
  --================================================================================
  -------------------------------【執行sql文】--------------------------------------
  --================================================================================
  
/* 期間管理報告清算提示 Start */

  -- 開啓日誌輸出緩衝
  DBMS_OUTPUT.ENABLE(buffer_size => null);
  -- 獲取當月的第一天和最後一天
  SELECT to_char(last_day(to_date(substr(c_startDate,0,7)||'-01', 'yyyy-mm-dd')), 'yyyy-mm-dd') INTO c_firstMonthDay FROM dual;
  --SELECT to_char(to_date(substr(c_startDate,0,7)||'-01', 'yyyy-mm-dd'), 'yyyy-mm-dd') INTO c_lastMonthDay FROM dual;
  c_N := 1;
  
  -- 生成第一次提示日期
   SELECT extract(YEAR FROM to_date(c_startDate, 'yyyy-mm-dd'))||'-'||'01'||'-'||'01'
         INTO c_firstClearDate FROM dual;
   c_clearDate := c_firstClearDate;
   
   -- 披露日期小於系統日期生成期間管理報告清算提示
   LOOP EXIT WHEN (c_clearDate > c_startDate);
        -- 直接生成收益分配提示
        dbms_output.put_line('披露日期爲:' || c_clearDate);
        dbms_output.put_line('傳入日期爲:' || c_startDate);
        dbms_output.put_line('進入循環,說明首次進入循環不做條件判斷');
        -- 用第一次提示日期計算下一次的提示日期
        SELECT to_char(add_months(to_date(c_firstClearDate, 'yyyy-mm-dd'), c_N*12), 'yyyy-MM-')||'01' INTO c_clearDate FROM dual;
        c_N := c_N + 1;
   END LOOP;

  
/* 期間管理報告清算提示 End */

  --輸出放回狀態信息
  v_res       := 0;
  v_errorCode := SQLCODE;
  v_errorMsg  := 'P_TEST' || ':' || TO_CHAR(SQLERRM);

  COMMIT;

--異常處理
EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
    v_res       := -1;
    v_errorCode := SQLCODE;
    v_errorMsg  := 'P_TEST' || ':' || TO_CHAR(SQLERRM);
END P_TEST; 

編寫完成,通過測試代碼:

begin
  -- Call the procedure
  p_test(v_res => :v_res,
         v_errorcode => :v_errorcode,
         v_errormsg => :v_errormsg,
         c_startdate => '2018-10-17');
end;

可以通過debug模式一步一步觀察代碼執行,

我把存儲過程執行結果的日誌貼出來

1438593-20190311221310270-2089376477.png

通過打印的日誌也可以得出結論:先進入循環,當滿足條件,跳出結束循環~

就OK的啦~~~~
1438593-20190311221302543-1452219009.png

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