MySql遊標、LOOP循環、REPEAT循環、LEAVE跳出循環、sql執行異常處理(判斷標記即可)

示例

DELIMITER $$
DROP PROCEDURE IF EXISTS `sp_cursor_test3` $$
CREATE PROCEDURE `sp_cursor_test3`()
top:BEGIN
  -- 錯誤標記,當sql執行出錯的時候,設置標記等於1。
  DECLARE _err INT DEFAULT 0;
    
    DECLARE fname LONGTEXT DEFAULT '';
    
    DECLARE msg LONGTEXT DEFAULT '';
    
    -- 定義局部變量:判斷是否完成和數量
  DECLARE done BOOLEAN DEFAULT 0;
    
    -- 定義遊標1
    DECLARE cs1 CURSOR FOR
    SELECT CONCAT(first_name,'1') FROM stu;
    
    -- 定義遊標2
    DECLARE cs2 CURSOR FOR
    SELECT CONCAT(first_name,'2') FROM stu;
    
    -- 當fetch遊標到了數據庫表格最後一行的時候,設置done=1。
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
    
    -- 錯誤標記處理,放到最後再聲明,要放到遊標後面。
    -- 不然會報錯:Variable or condition declaration after cursor or handler declaration
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION,SQLWARNING,NOT FOUND set _err=1;
    
    -- 在開始循環之前修改數據,循環會使用新數據。
    -- UPDATE stu SET first_name=DATE_FORMAT(NOW(),'%Y-%m-%d %h:%i:%s') WHERE id=1;
    
    -- 打開遊標    
    OPEN cs1;
    -- 每開始一個循環,重置循環結束標記。
    SET done = 0;
    -- LOOP循環標記
    read_loop: LOOP
      -- FETCH 遊標中的列必須要和INTO的列數量和類型一致。
        -- 如果遊標中沒有新的可用行,即Fetch到空行,則會觸發NOT FOUND異常,就會把done設置爲1。
      FETCH cs1 INTO fname;
        -- 執行邏輯前必須要判斷標記,否則會多出一次循環。
        IF(done = 0)
        THEN
          -- 處理FETCH到的數據
          SET msg = CONCAT(msg,fname,'/');
        ELSE
        -- 關閉遊標
        CLOSE cs1;
          -- 跳出循環標記
            LEAVE read_loop;
        END IF;
    -- 結束標記,在循環體中判斷並跳出。
  END LOOP;
    -- 關閉遊標
    CLOSE cs1;
    
    
    -- 遊標2    
    OPEN cs2;
    SET done = 0;
    -- REPEAT循環
    REPEAT
      -- FETCH 遊標中的列必須要和INTO的列數量和類型一致。
        -- 如果遊標中沒有新的可用行,即Fetch到空行,則會觸發NOT FOUND異常,就會把done設置爲1。
      FETCH cs2 INTO fname;
        -- 執行邏輯前必須要判斷標記,否則會多出一次循環。
        IF(done = 0)
        THEN
          SET msg = CONCAT(msg,fname,'/');
        END IF;
    -- 通過判斷done來結束循環
  UNTIL done END REPEAT;
    -- 關閉遊標
    CLOSE cs2;
    
    SELECT msg;
    
END $$
DELIMITER ;

 

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