什麼是存儲過程?
存儲於資料庫中的程式碼單元,類似程式語言的子程序。MySQL 5.0 支援兩類 Routine:存儲過程 (CALL 調用、無返回值) 與 函數 (SQL 表達式中調用、有返回值,如 `PI()`)。
結構組成
CREATE PROCEDURE proc_name (IN param INT)
BEGIN
DECLARE var CHAR(10);
IF param = 17 THEN SET var = 'birds';
ELSE SET var = 'beasts'; END IF;
INSERT INTO table1 VALUES (var);
END;
- 名稱、參數列表、SQL 語句集 (含變量、流程控制、異常處理)
為何使用存儲過程?
- 成熟技術:Oracle/DB2/SQL Server 早已普及,文檔豐富、人才易覓
- 效能提升:減少網路往返 (特別是批次邏輯)、利用伺服器快取 (類 Prepared Statement)
- 可復用/可移植:純 SQL 撰寫,跨平台、跨應用語言、邏輯集中維護
- 原始碼持久化:邏輯與資料同庫存儲,版本可追溯
- 標準相容:MySQL 5.0 完整支援 SQL:2003 標準
環境啟動檢查清單
- 執行 `mysql_fix_privilege_tables` 或 `mysql_install_db` 建立 `mysql.proc` 表
- Root 登入:`mysql --user=root`
- 驗證版本:`SELECT VERSION();` → 必見
5.0.x
- 建立練習庫:`CREATE DATABASE db5; USE db5;`
- 建立測試表:`CREATE TABLE t (s1 INT); INSERT INTO t VALUES (5);`
- 設定分隔符:`DELIMITER //` (避免過程內分號衝突,結束用 `//`,還原用 `DELIMITER ;`)
第一個存儲過程
CREATE PROCEDURE p1 () SELECT * FROM t; //
- `CREATE PROCEDURE`:關鍵字
- `p1`:名稱 (不區分大小寫、長度≤64、同庫不可重名、避開內建函數名)
- `()`:參數列表 (此處為空,括號必寫)
- `SELECT * FROM t;`:過程體 (單句可無 BEGIN/END)
調用驗證
MySQL> CALL p1(); //
+------+
| s1 |
+------+
| 5 |
+------+
1 row in set (0.03 sec)
標識符命名規則
- 不區分大小寫:`P1` = `p1`
- 可含空格、點號 (跨庫 `db5.p1`)
- 避開內建函數名 (如 `PI`) ,否則呼叫需加空格 `CALL PI ();`