| 模式 | 方向 | 說明 |
| IN | 輸入 | 預設,呼叫端傳入,過程內不可修改原值 |
| OUT | 輸出 | 過程內賦值,呼叫端透過用戶變數 `@var` 接收 |
| INOUT | 雙向 | 呼叫端傳入,過程可修改,呼叫端取回新值 |
OUT 參數範例:價格統計
CREATE PROCEDURE productpricing(
OUT pl DECIMAL(8,2),
OUT ph DECIMAL(8,2),
OUT pa DECIMAL(8,2)
)
BEGIN
SELECT MIN(prod_price) INTO pl FROM products;
SELECT MAX(prod_price) INTO ph FROM products;
SELECT AVG(prod_price) INTO pa FROM products;
END;
CALL productpricing(@low, @high, @avg);
SELECT @low, @high, @avg;
IN + OUT 範例:訂單總額
CREATE PROCEDURE ordertotal(
IN onumber INT,
OUT ototal DECIMAL(8,2)
)
BEGIN
SELECT SUM(item_price * quantity) INTO ototal
FROM orderitems WHERE order_num = onumber;
END;
CALL ordertotal(20005, @total);
SELECT @total;
動態分頁通用過程(生產級)
DELIMITER $$
CREATE PROCEDURE get_page(
IN tableName VARCHAR(100),
IN fieldsNames VARCHAR(100),
IN pageIndex INT,
IN pageSize INT,
IN sortName VARCHAR(500),
IN strWhere VARCHAR(500)
)
BEGIN
DECLARE fieldlist VARCHAR(200);
SET fieldlist = IF(fieldsNames='' OR fieldsNames IS NULL, '*', fieldsNames);
SET @strSQL = CONCAT('SELECT ', fieldlist, ' FROM ', tableName);
IF strWhere != '' AND strWhere IS NOT NULL THEN
SET @strSQL = CONCAT(@strSQL, ' WHERE ', strWhere);
END IF;
IF sortName != '' AND sortName IS NOT NULL THEN
SET @strSQL = CONCAT(@strSQL, ' ORDER BY ', sortName);
END IF;
SET @strSQL = CONCAT(@strSQL, ' LIMIT ', (pageIndex-1)*pageSize, ',', pageSize);
PREPARE stmt1 FROM @strSQL;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END$$
DELIMITER ;
呼叫:CALL get_page('products', 'prod_id,prod_name', 1, 10, 'prod_price', 'prod_price > 100');
管理指令速查
SHOW CREATE PROCEDURE proc_name;
DROP PROCEDURE [IF EXISTS] proc_name;
-- ALTER PROCEDURE 僅能修改特性(如 SQL SECURITY),不可修改邏輯
最佳實踐提醒
- 所有參數必須宣告型別(如 `DECIMAL(8,2)`、`INT`、`VARCHAR(100)`)
- 動態 SQL 使用 `PREPARE/EXECUTE/DEALLOCATE` 防注入
- 過程內避免長事務、大量資料處理,影響並發
- 命名規範:`sp_` 前綴區分系統/業務過程
- 上一篇文章: MySQL GRANT 權限管理完整指南:分層授權、撤銷、最佳實踐
- 下一篇文章: PHP 呼叫 MySQL 存儲過程實戰:mysqli 多結果集處理與完整 CRUD 範例
Copyright ©
程式碼之家 All Rights Reserved