MYSQL存儲過程常見操做誤區 - 遊標(CURSOR) - 函數,過程調用 - 遞歸操做

這兩天在作一些簡單的存儲過程,之前並未涉及過,現學現賣,碰到了很多問題,找了不少資料,也差很少解決了,廢話很少說,但願用本身的失敗經驗給猿們提供點幫助。函數

 

  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;
    
    後面的數值根據本身的狀況設置,表示想要遞歸的層級


    總結:新熟悉一個東西都會有很大的難度,可是網上已經有不少前輩給的方法解決,你們必定要多動手多瞭解,可能我這裏有說的錯誤的地方,但願多多理解,有問題就回復,我好更改,哈哈。
相關文章
相關標籤/搜索