預存程序是預先編譯並儲存在資料庫中的 SQL 程式碼單元,可接受參數、包含流程控制邏輯,並能透過名稱重複呼叫。MySQL 5.0+ 開始支援,大幅提升資料庫程式設計的靈活性與效能。
CALL proc_name(params),而非大量 SQL 文本GRANT EXECUTE ON proc TO user 授權,隱藏底層表結構與 SQL 細節CREATE PROCEDURE 程序名 ([參數列表])
[特性 ...]
BEGIN
-- 程序體:SQL 陳述式 + 流程控制
END;
DELIMITER //
CREATE PROCEDURE demo_proc (OUT s INT)
BEGIN
SELECT COUNT(*) INTO s FROM my_table;
END //
DELIMITER ;
MySQL 預設以
;為陳述式結束,程序體內含多個;需先以DELIMITER //變更分隔符,結束後恢復DELIMITER ;。
| 模式 | 關鍵字 | 方向 | 用途 |
|---|---|---|---|
| 輸入 | IN | 呼叫端 → 程序 | 傳入條件值、設定參數 |
| 輸出 | OUT | 程序 → 呼叫端 | 回傳計算結果、狀態碼 |
| 雙向 | INOUT | 雙向 | 傳入初值,程序修改後回傳 |
CREATE PROCEDURE calc_bonus (
IN emp_id INT,
IN base_sal DECIMAL(10,2),
OUT bonus DECIMAL(10,2),
INOUT tax_rate DECIMAL(3,2)
)
BEGIN
SET bonus = base_sal * 0.15;
SET tax_rate = tax_rate * 1.05; -- 調整稅率
END;
IF ... THEN ... ELSEIF ... ELSE ... END IF / CASE ... WHEN ... THEN ... ELSE ... END CASEWHILE ... DO ... END WHILE / REPEAT ... UNTIL ... END REPEAT / LOOP ... END LOOP(需配合 LEAVE 跳出)label_name: BEGIN ... LEAVE label_name; ... ENDDECLARE var_name data_type [DEFAULT default_value]; SET var_name = expression; SELECT column INTO var_name FROM table WHERE ...;
-- 呼叫 CALL proc_name(arg1, arg2, ...); -- 刪除 DROP PROCEDURE IF EXISTS proc_name;
GRANT EXECUTE ON PROCEDURE db.proc_name TO 'user'@'host'; REVOKE EXECUTE ON PROCEDURE db.proc_name FROM 'user'@'host';
DELIMITER //
CREATE PROCEDURE sp_page_query (
IN p_table VARCHAR(64),
IN p_page_num INT,
IN p_page_size INT,
OUT p_total_rows INT
)
BEGIN
DECLARE v_offset INT;
DECLARE v_sql TEXT;
-- 計算總筆數
SET @sql_count = CONCAT('SELECT COUNT(*) INTO @total FROM ', p_table);
PREPARE stmt FROM @sql_count;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET p_total_rows = @total;
-- 分頁查詢
SET v_offset = (p_page_num - 1) * p_page_size;
SET v_sql = CONCAT('SELECT * FROM ', p_table, ' LIMIT ', v_offset, ', ', p_page_size);
PREPARE stmt FROM v_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
預存程序是資料庫開發的重要工具,善用可提升系統效能、安全性與維護性。