DROP PROCEDURE IF EXISTS pr_dealtestnum; DELIMITER // CREATE PROCEDURE pr_dealtestnum (IN p_boxnumber VARCHAR(30)) pr_dealtestnum_label:BEGIN INSERT INTO tb_testnum SELECT boxnumber, usertype FROM tb_testnum_tmp WHERE boxnumber = p_boxnumber; LEAVE pr_dealtestnum_label; END; // DELIMITER ;
表結構:
-- 目標表 CREATE TABLE tb_testnum ( boxnumber VARCHAR(30) NOT NULL, usertype INT NOT NULL, UNIQUE KEY idx1_tb_testnum (boxnumber) ) ENGINE=InnoDB; -- 源表 CREATE TABLE tb_testnum_tmp ( boxnumber VARCHAR(30) NOT NULL, usertype INT NOT NULL, UNIQUE KEY idx1_tb_testnum_tmp (boxnumber) ) ENGINE=InnoDB;
DECLARE p_usertype INT; SELECT usertype INTO p_usertype FROM tb_testnum_tmp WHERE boxnumber = p_boxnumber; INSERT INTO tb_testnum VALUES (p_boxnumber, p_usertype);
收益:SQL 與業務邏輯分離,便於單獨驗證查詢結果,異常時精確定位是查詢還是插入失敗。
DECLARE p_datacount INT; -- 源表存在性 SELECT COUNT(*) INTO p_datacount FROM tb_testnum_tmp WHERE boxnumber = p_boxnumber; IF p_datacount = 0 THEN LEAVE pr_dealtestnum_label; END IF; SELECT usertype INTO p_usertype FROM tb_testnum_tmp WHERE boxnumber = p_boxnumber; -- 目標表唯一性 SELECT COUNT(*) INTO p_datacount FROM tb_testnum WHERE boxnumber = p_boxnumber; IF p_datacount > 0 THEN LEAVE pr_dealtestnum_label; END IF; INSERT INTO tb_testnum VALUES (p_boxnumber, p_usertype);
收益:業務邏輯層面保證冪等性,不依賴數據庫報錯回滾,性能更優(COUNT 走索引極快)。
CREATE PROCEDURE pr_dealtestnum ( IN p_boxnumber VARCHAR(30), OUT p_result INT -- 0 成功,1 源表無數據,2 目標表已存在 ) -- 內部各分支 SET p_result = 對應碼; LEAVE ...
收益:調用方無需捕獲異常即可知曉業務狀態,便於上層重試/告警邏輯。
INSERT INTO tb_testnum (boxnumber, usertype) VALUES (p_boxnumber, p_usertype);
收益:未來給 tb_testnum 新增列(如 create_time)時,存儲過程不會報錯,實現向後兼容。
@error_count 確認寫入真正成功INSERT INTO tb_testnum (boxnumber, usertype) VALUES (p_boxnumber, p_usertype); IF @error_count <> 0 THEN SET p_result = 3; -- 寫入失敗(如磁盤滿、鎖等待超時) ELSE SET p_result = 0; END IF;
收益:捕獲運行時異常(非邏輯錯誤),區分業務失敗與系統故障。
DROP PROCEDURE IF EXISTS pr_dealtestnum; DELIMITER // CREATE PROCEDURE pr_dealtestnum ( IN p_boxnumber VARCHAR(30), OUT p_result INT -- 0=成功 1=源無數據 2=目標已存在 3=寫入異常 ) pr_dealtestnum_label:BEGIN DECLARE p_usertype INT; DECLARE p_datacount INT; -- 源表校驗 SELECT COUNT(*) INTO p_datacount FROM tb_testnum_tmp WHERE boxnumber = p_boxnumber; IF p_datacount = 0 THEN SET p_result = 1; LEAVE pr_dealtestnum_label; END IF; SELECT usertype INTO p_usertype FROM tb_testnum_tmp WHERE boxnumber = p_boxnumber; -- 目標表唯一性校驗 SELECT COUNT(*) INTO p_datacount FROM tb_testnum WHERE boxnumber = p_boxnumber; IF p_datacount > 0 THEN SET p_result = 2; LEAVE pr_dealtestnum_label; END IF; -- 執行插入並檢查運行時錯誤 INSERT INTO tb_testnum (boxnumber, usertype) VALUES (p_boxnumber, p_usertype); IF @error_count <> 0 THEN SET p_result = 3; ELSE SET p_result = 0; END IF; LEAVE pr_dealtestnum_label; END; // DELIMITER ;
DROP ... CREATE 納入遷移腳本,Git 追蹤變更