MySQL 提供過程化編程能力,支持變量、流程控制、自定義函數 (UDF)、存儲過程、觸發器。本文系統梳理語法規則、作用域陷阱、最佳實踐模式。
-- 默認 ; 和 \g (僅命令行)
DELIMITER $$ -- 臨時修改為 $$
-- 函數/過程體內部用 ; 結尾
END$$
DELIMITER ; -- 恢復默認
# comment、-- comment (雙減號後需空格)/* comment */| 類型 | 語法 | 作用域 | 生命周期 |
|---|---|---|---|
| 系統變量 | SHOW VARIABLES LIKE 'pat%'; SET GLOBAL sort_buffer_size=... | 全局/會話 | 服務運行期 |
| 用戶會話變量 | SET @var=val; SELECT @var; | 會話級 | 連接斷開失效 |
| 局部變量 | DECLARE var TYPE DEFAULT val; (僅 BEGIN...END 內) | 塊級 | 塊結束失效 |
⚠️ 陷阱:函數/過程內使用
@var會污染會話變量,必須用 DECLARE 定義局部變量。
IF cond1 THEN ... ELSEIF cond2 THEN ... ELSE ... END IF;
CASE var WHEN v1 THEN ... WHEN v2 THEN ... ELSE ... END CASE;
WHILE cond DO ... END WHILE; (先判斷)REPEAT ... UNTIL cond END REPEAT; (後判斷,至少一次)LOOP ... END LOOP; (無條件,配合 LEAVE label、ITERATE label)-- 帶標籤循環
my_loop: LOOP
SET i = i + 1;
IF i = 5 THEN ITERATE my_loop; END IF; -- 跳過本輪
IF i > 10 THEN LEAVE my_loop; END IF; -- 跳出循環
END LOOP my_loop;
DROP FUNCTION IF EXISTS my_sum;
DELIMITER $$
CREATE FUNCTION my_sum() RETURNS INT
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE sum INT DEFAULT 0;
WHILE i <= 100 DO
SET sum = sum + i;
SET i = i + 1;
END WHILE;
RETURN sum;
END$$
DELIMITER ;
SELECT my_sum(); -- 5050
IN,支持 OUT/INOUT (過程專用,函數僅支持 IN)。DETERMINISTIC (相同輸入必得相同輸出),利於優化器緩存。| 分類 | 常用函數 |
|---|---|
| 數值 | ABS()、CEIL()、FLOOR()、ROUND(x,d)、RAND()、MOD() |
| 字符串 | CONCAT()、SUBSTRING()、TRIM()、REPLACE()、LPAD/RPAD()、LOWER/UPPER() |
| 日期 | NOW()、CURDATE()、DATE_FORMAT()、UNIX_TIMESTAMP()、FROM_UNIXTIME() |
| 流程控制 | IF()、IFNULL()、CASE WHEN |
| 信息 | DATABASE()、VERSION()、USER()、INET_ATON/NTOA() |