這兩天在作一些簡單的存儲過程,之前並未涉及過,現學現賣,碰到了很多問題,找了不少資料,也差很少解決了,廢話很少說,但願用本身的失敗經驗給猿們提供點幫助。函數
1. select into 致使遊標處理未所有完成spa
#通常來說,咱們會在某個過程(帶有遊標或其餘循環操做)開始以前定義一個處理完畢的標識code
DECLARE done INT DEFAULT 0;遞歸
#設置遊標信息 (以查詢 a 表 id 爲實例) it
DECLARE a_id INT DEFAULT 0;
DECLARE b_id INT DEFAULT 0;io
DECLARE cur CURSOR FOR (
SELECT ` id` FROM `a_table`;
); table
#然而通常咱們也會在出現錯誤或者其餘狀況下重置done的值,以下:function
#出現異常(SQLSTATE 02000 | NOT FOUND)
DECLARE CONTINUE HANDLER for SQLSTATE '02000' SET done = 1;class
#而後開始遊標變量
OPEN cur;
#獲取第一層遊標
FETCH cur INTO a_id;
#開始循環處理(While)
WHILE (done = 0) DO
#查詢關聯信息(這句在某些狀況下會出現錯誤,致使遊標結束)
SELECT `id` INTO b_id from `b_table` WHERE `a_id` = a_id;
#獲取下一層遊標,並繼續循環
FETCH cur INTO o_model_name;
#結束循環處理
END WHILE;
#結束遊標
CLOSE cur;
廢話說了這麼多,寫了個簡單的例子,簡單的說說會出現問題的緣由,正常來講,當b_table中不存在a_id對應的ID值時,將返回null,但因爲DECLARE CONTINUE HANDLER for SQLSTATE '02000' SET done = 1;當出現查詢爲null的狀況時,將會重置done爲1,從而不在執行後面的遊標,解決方案以下:
SELECT `id` INTO b_id from `b_table` WHERE `a_id` = a_id;
更改成
SET b_id = (SELECT `id` FROM `b_table` WHERE `a_id` = a_id);
後續邏輯可直接判斷b_id的值
IF b_id != '' THEN
#處理邏輯
END IF;
2. function(函數) 與 PROCEDURE(過程)的不一樣調用方法
function 採用 SELECT 調用,通常會返回返回值,因此最好先定義一個變量用於儲存返回值(若是須要),如帶參數可直接對應賦值參數便可。
DECLARE a_result VARCHAR(100) DEFAULT '';
SELECT function_A([param_1,param_2]) INTO a_result;
procedure 採用 CALL 調用,沒有返回值,主要處理邏輯,可傳參數,特別注意的是:請留意 IN ,OUT ,INOUT三種模式,具體區別百度一下,講的比我清楚。
DECLARE param_1 INT DEFAULT 0;
CALL procedure_A(param_1);
3. 遞歸操做
說實話剛開始使用遞歸是真把我難到了,網上也沒有準確的操做方法,慢慢摸索才理清楚,這裏也不出例子了,其實就是結合function(函數) 與 PROCEDURE(過程)就能完美的呈現遞歸操做,這裏強調一點,當遞歸操做時,通常會報
ERROR 1456 (HY000): Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine
等錯誤,那是由於默認狀況下是不容許使用遞歸操做的,這裏須要在須要遞歸操做前生命一個系統變量:
SET @@max_sp_recursion_depth = 100;
後面的數值根據本身的狀況設置,表示想要遞歸的層級
總結:新熟悉一個東西都會有很大的難度,可是網上已經有不少前輩給的方法解決,你們必定要多動手多瞭解,可能我這裏有說的錯誤的地方,但願多多理解,有問題就回復,我好更改,哈哈。