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

MySQL 存儲過程實戰範例:事務控制、輸出參數、游標迴圈、嵌套呼叫

     編輯:MySQL 資料庫相關知識

主程序:增量同步邏輯

DROP PROCEDURE IF EXISTS pro_rep_shadow_rs;
DELIMITER |

CREATE PROCEDURE pro_rep_shadow_rs(OUT rtn INT)
BEGIN
    -- 變數宣告(必須在最前面)
    DECLARE iLast_rep_sync_id INT DEFAULT -1;
    DECLARE iMax_rep_sync_id INT DEFAULT -1;

    -- 異常處理:遇到 SQL 異常自動回滾
    DECLARE EXIT HANDLER FOR SQLEXCEPTION 
    BEGIN
        ROLLBACK;
        SET rtn = 0;
    END;

    -- 取得上次同步位點
    SELECT eid INTO iLast_rep_sync_id 
    FROM rep_de_proc_log WHERE tbl = 'rep_shadow_rs';

    -- 首次執行初始化
    IF iLast_rep_sync_id = -1 THEN
        INSERT INTO rep_de_proc_log(rid, eid, tbl) VALUES (0, 0, 'rep_shadow_rs');
        SET iLast_rep_sync_id = 0;
    END IF;

    SET iLast_rep_sync_id = iLast_rep_sync_id + 1;
    SET rtn = 0;  -- 預設失敗

    START TRANSACTION;

    -- 取得最大同步 ID
    SELECT MAX(rep_sync_id) INTO iMax_rep_sync_id FROM rep_shadow_rs;

    -- 有新資料才處理
    IF iMax_rep_sync_id >= iLast_rep_sync_id THEN
        CALL pro_rep_shadow_rs_do(iLast_rep_sync_id, iMax_rep_sync_id);
        UPDATE rep_de_proc_log 
        SET rid = iLast_rep_sync_id, eid = iMax_rep_sync_id 
        WHERE tbl = 'rep_shadow_rs';
    END IF;

    COMMIT;
    SET rtn = 1;  -- 成功
END |

DELIMITER ;

子程序:游標逐行處理

DROP PROCEDURE IF EXISTS pro_rep_shadow_rs_do;
DELIMITER |

CREATE PROCEDURE pro_rep_shadow_rs_do(
    IN last_rep_sync_id INT,
    IN max_rep_sync_id INT
)
BEGIN
    DECLARE iRep_operationtype CHAR(1);
    DECLARE iRep_status CHAR(1);
    DECLARE iRep_Sync_id INT;
    DECLARE iId INT;
    DECLARE stop INT DEFAULT 0;

    -- 宣告游標
    DECLARE cur CURSOR FOR 
        SELECT id, Rep_operationtype, Rep_status, rep_sync_id
        FROM rep_shadow_rs
        WHERE rep_sync_id BETWEEN last_rep_sync_id AND max_rep_sync_id;

    -- 游標結束處理
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET stop = 1;

    OPEN cur;

    FETCH cur INTO iId, iRep_operationtype, iRep_status, iRep_Sync_id;

    WHILE stop <> 1 DO
        IF iRep_operationtype = 'I' THEN
            INSERT INTO rs0811 (id, fnbm) 
            SELECT id, fnbm FROM rep_shadow_rs WHERE rep_sync_id = iRep_Sync_id;
        ELSEIF iRep_operationtype = 'U' THEN
            IF iRep_status = 'A' THEN
                INSERT INTO rs0811 (id, fnbm) 
                SELECT id, fnbm FROM rep_shadow_rs WHERE rep_sync_id = iRep_Sync_id;
            ELSEIF iRep_status = 'B' THEN
                DELETE FROM rs0811 WHERE id = iId;
            END IF;
        ELSEIF iRep_operationtype = 'D' THEN
            DELETE FROM rs0811 WHERE id = iId;
        END IF;

        FETCH cur INTO iId, iRep_operationtype, iRep_status, iRep_Sync_id;
    END WHILE;

    CLOSE cur;
END |

DELIMITER ;

關鍵技術點解析

技術說明
OUT 參數OUT rtn INT 回傳執行狀態,呼叫端用 CALL proc(@rtn); SELECT @rtn; 取得
事務控制START TRANSACTION / COMMIT / ROLLBACK,搭配 EXIT HANDLER 自動回滾
游標DECLARE CURSOR + OPEN/FETCH/CLOSE,配合 NOT FOUND HANDLER 控制迴圈
嵌套呼叫主程序 CALL 子程序,參數傳遞位點範圍
增量同步透過 rep_de_proc_log 記錄上次處理位點,避免重複處理

呼叫測試

CALL pro_rep_shadow_rs(@rtn);
SELECT @rtn;  -- 1 成功,0 失敗
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved