首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 游標完整指南:聲明、循環遍歷與異常處理實戰

     編輯:MySQL 資料庫相關知識

MySQL 游標基礎概念

游標是存儲過程中用於逐行處理結果集的機制。MySQL 游標具有只讀、單向、不可滾動特性,適用於需要逐行邏輯處理的場景,如複雜數據轉換、批量業務邏輯執行等。

核心語法結構

-- 1. 聲明游標
DECLARE cursor_name CURSOR FOR SELECT_statement;

-- 2. 聲明處理器(異常捕獲)
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

-- 3. 打開游標
OPEN cursor_name;

-- 4. 獲取數據
FETCH cursor_name INTO var1, var2, ...;

-- 5. 關閉游標
CLOSE cursor_name;

三種循環遍歷模式實戰

模式一:WHILE 循環(預讀模式)

CREATE PROCEDURE useCursor()
BEGIN
    DECLARE tmpName VARCHAR(20) DEFAULT '';
    DECLARE allName VARCHAR(255) DEFAULT '';
    DECLARE cur1 CURSOR FOR SELECT name FROM test.level;
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET tmpName = NULL;

    OPEN cur1;
    FETCH cur1 INTO tmpName;  -- 預讀第一行

    WHILE (tmpName IS NOT NULL) DO
        SET tmpName = CONCAT(tmpName, ';');
        SET allName = CONCAT(allName, tmpName);
        FETCH cur1 INTO tmpName;  -- 讀取下一行
    END WHILE;

    CLOSE cur1;
    SELECT allName;
END;

關鍵點:必須在循環前預讀一次,循環末尾再次 FETCH,通過 handler 將 NOT FOUND 轉為變量 NULL 終止循環。

模式二:LOOP 循環(標準模式)

CREATE PROCEDURE cursor_example()
READS SQL DATA
BEGIN
    DECLARE l_employee_id INT;
    DECLARE l_salary NUMERIC(8,2);
    DECLARE l_department_id INT;
    DECLARE done INT DEFAULT 0;
    DECLARE cur1 CURSOR FOR SELECT employee_id, salary, department_id FROM employees;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    OPEN cur1;
    emp_loop: LOOP
        FETCH cur1 INTO l_employee_id, l_salary, l_department_id;
        IF done = 1 THEN
            LEAVE emp_loop;
        END IF;
        -- 處理邏輯
    END LOOP emp_loop;
    CLOSE cur1;
END;

優勢:結構清晰,FETCH 與判斷緊湊結合,標籤支持嵌套循環控制。

模式三:REPEAT 循環(後測試模式)

CREATE PROCEDURE test()
BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE a VARCHAR(200) DEFAULT '';
    DECLARE c VARCHAR(200) DEFAULT '';
    DECLARE mycursor CURSOR FOR SELECT fusername FROM uchome_friend;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    OPEN mycursor;
    REPEAT
        FETCH mycursor INTO a;
        IF NOT done THEN
            SET c = CONCAT(c, a);
        END IF;
    UNTIL done END REPEAT;
    CLOSE mycursor;
    SELECT c;
END;

特點:至少執行一次 FETCH,適合確定有數據的場景。

最佳實踐與注意事項

  • 必須聲明 NOT FOUND handler,否則游標讀完會報錯終止過程
  • 游標變量需與 SELECT 列數量、類型一一對應
  • 使用 READS SQL DATA 特性聲明提升優化器判斷
  • 及時 CLOSE 釋放資源,避免連接洩漏
  • 大數據量慎用游標,集合操作(JOIN、子查詢)通常效率更高

常見錯誤排查

錯誤現象原因解決
Cursor fetch returns no data未聲明 handler 或邏輯錯誤檢查 CONTINUE HANDLER 聲明
Variables not updatedFETCH INTO 變量順序/類型不匹配核對聲明順序與 SELECT 列
Infinite loop缺少 FETCH 或 handler 未生效確保循環體內有 FETCH,handler 正確設置
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved