本隨筆文章,由我的博客(鳥不拉屎)轉移至博客園 發佈時間: 2018 年 10 月 17 日 原地址:https://niaobulashi.com/archives/procedures_loop.htmlhtml
###存儲過程LOOP疑問sql
今天在開發需求時,須要編寫一個存儲過程,實現數據的初始化功能。oop
發現遇到循環處理時,跳出循環的條件,Loop的處理學習
LOOP EXIT WHRN(P1 > P2); ... END LOOP;
emmmmmm,由於以前沒有怎麼學習存儲過程,只是看了一下存儲過程的原理,就上手開發了(所謂了敏捷開發哈哈哈哈哈哈)測試
就引發個人疑問:是直接進入循環呢?仍是先判斷條件?url
我上網查閱資料。。。好像沒有查閱到額.net
不過看到有一個類型的,我貼出來debug
loop v_sal := v_sal + 1; dbms_output.put_line(v_sal); exit when v_sal = 8000; end loop
這個類比Java的do-while形式是同樣的:先進入循環,知足條件了跳出循環日誌
我就猜想code
第一種也是這種類型的
因而我寫了個測試例子,存儲過程代碼以下:
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模式一步一步觀察代碼執行,
我把存儲過程執行結果的日誌貼出來
經過打印的日誌也能夠得出結論:先進入循環,當知足條件,跳出結束循環~
就OK的啦~~~~