首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 存儲過程入門:創建、調用、參數模式、流程控制與性能優勢全解析

     編輯:MySQL 綜合教學

為什麼用存儲過程?

  • 封裝業務邏輯:將複雜 SQL 與條件判斷下沉到數據庫層,應用代碼僅調用 CALL proc()
  • 減少網絡往返:批量操作單次交互完成
  • 執行計劃復用:首次編譯後緩存,後續調用省去解析優化
  • 權限隔離:應用賬號僅需 EXECUTE 權限,無需直接表操作權限

基礎語法

DELIMITER $$

CREATE PROCEDURE `proc_name` (
    IN  p_param1 INT,      -- 輸入參數
    OUT p_param2 VARCHAR(64), -- 輸出參數
    INOUT p_param3 INT     -- 輸入輸出參數
)
BEGIN
    DECLARE v_local_var INT DEFAULT 0;  -- 局部變量

    -- 流程控制
    IF p_param1 > 0 THEN
        SET v_local_var = p_param1 * 2;
    ELSE
        SET v_local_var = 0;
    END IF;

    -- 賦值輸出參數
    SET p_param2 = CONCAT('Result: ', v_local_var);
    SET p_param3 = v_local_var;

    -- 多語句需 BEGIN ... END 包裹
    INSERT INTO log_tbl (msg) VALUES (p_param2);
END$$

DELIMITER ;

調用方式

-- 1. 用戶變量接收輸出
SET @out1 = '', @out2 = 0;
CALL proc_name(10, @out1, @out2);
SELECT @out1, @out2;

-- 2. 直接在 SELECT 中調用(僅支持 IN 參數)
SELECT func_name(10);  -- 函數而非過程

參數模式對比

模式關鍵字方向調用時需變量
輸入IN應用 → 過程否(可直接傳常量)
輸出OUT過程 → 應用是(用戶變量 @var)
輸入輸出INOUT雙向是

流程控制構造

  • IF ... THEN ... ELSEIF ... ELSE ... END IF;
  • CASE WHEN ... THEN ... ELSE ... END CASE;
  • WHILE condition DO ... END WHILE;
  • REPEAT ... UNTIL condition END REPEAT;
  • LOOP ... END LOOP; + LEAVE label; / ITERATE label;
  • DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @err = 1; 異常處理

性能優化建議

  1. 避免在過程中單條循環 INSERT,改用批量構造值列表或 LOAD DATA
  2. 適當使用 PREPARE / EXECUTE 動態 SQL,但注意準備語句緩存限制
  3. 輸出參數盡量用 OUT 而非結果集,減少網絡傳輸
  4. 高併發熱點過程考慮 GET_LOCK() 互斥或拆分粒度

版本差異提示

  • MySQL 5.0+ 支持存儲過程
  • 5.7+ 支持 sys.schema_unused_indexes 等元數據視圖輔助治理
  • 8.0 引入 CTE、窗口函數,複雜邏輯可在單 SQL 完成,減少過程依賴

存儲過程是邊界清晰、邏輯相對固定、高頻執行場景的利器;業務快速迭代、邏輯極其複雜時,優先考慮應用層實現,數據庫層保持瘦身。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved