MySQL 5.0 引入存儲過程,彌補以往缺乏程式邏輯封裝的短板。本文整理存儲過程的優缺點、SQL:2003 標準相容性、支援的 SQL 語句清單,並給出實務採用建議。
存儲過程是儲存在資料庫伺服器端的 SQL 命令與程式邏輯集合,可被應用程式呼叫。類似資料庫層的「函式庫」,將資料存取邏輯與業務邏輯分離。
EXECUTE 權限而不給直接存取表的權限(註:MySQL 早期版本未完整支援 GRANT EXECUTE,5.0+ 已支援)。| 語句 | 說明 |
|---|---|
CREATE PROCEDURE | 建立存儲過程 |
CREATE FUNCTION | 建立使用者自訂函數(回傳值) |
ALTER PROCEDURE / FUNCTION | 修改既有過程/函數特性 |
DROP PROCEDURE / FUNCTION | 刪除過程/函數 |
SHOW CREATE PROCEDURE / FUNCTION | 顯示建立語句 |
SHOW PROCEDURE / FUNCTION STATUS | 顯示元資料(建立者、時間等) |
CALL | 呼叫存儲過程 |
BEGIN ... END | 複合語句區塊 |
DECLARE | 宣告區域變數、游標、條件處理器 |
SET | 指派變數值 |
SELECT ... INTO | 查詢結果存入變數 |
OPEN / FETCH / CLOSE | 游標操作 |
IF / CASE | 條件判斷 |
LOOP / REPEAT / WHILE | 迴圈結構 |
LEAVE / ITERATE | 跳出/繼續迴圈 |
RETURN | 函數回傳值 |
DELIMITER //
CREATE PROCEDURE `GetUserOrders`(IN p_user_id INT, OUT p_total INT)
BEGIN
SELECT COUNT(*) INTO p_total FROM `orders` WHERE `user_id` = p_user_id;
SELECT * FROM `orders` WHERE `user_id` = p_user_id ORDER BY `created_at` DESC;
END //
DELIMITER ;
-- 呼叫
CALL GetUserOrders(123, @total);
SELECT @total;
sp_模組_動作)、詳細註釋、輸入參數驗證、錯誤處理(DECLARE CONTINUE HANDLER)、避免在過程中建立/刪除表(DDL 會導致隱含提交)。CREATE PROCEDURE 腳本存放於專案 SQL 遷移目錄,併入部署流程。EXPLAIN ANALYZE)、通用資料表運算式(CTE)支援大幅改善,建議直接使用 8.0+ 環境。存儲過程是把雙面刃:用得好能簡化架構、提升效能;用不好會讓資料庫成為瓶頸與維護噩夢。建議團隊在專案早期評估技術債與長期維運成本後再決定採用程度。