MySQL 儲存過程支援三種變數類型:區域變數、會話變數、全域變數。理解其作用域、生命週期與賦值方式,是編寫高效儲存過程的基礎。
DECLARE var_name data_type [DEFAULT default_value];
-- 多變數同類型可合併
DECLARE x, y INT DEFAULT 0;
BEGIN ... END 區塊內有效。
CREATE PROCEDURE sp_local_var_demo()
BEGIN
DECLARE v_count INT DEFAULT 0;
DECLARE v_name VARCHAR(50) DEFAULT 'test';
SET v_count = v_count + 1;
SELECT v_count, v_name;
END;
SET @var_name = value;
-- 或
SELECT @var_name := value;
@,無需聲明,MySQL 自動推斷型別。SET @var = NULL 時銷毀。
SET @total = 0;
SELECT @total := @total + 1 AS seq, id FROM users LIMIT 5;
-- 產生連續序號
SET GLOBAL var_name = value;
SET @@global.var_name = value;
-- 僅限系統變數,不可自訂
SUPER 權限(MySQL 5.7+ 需 SYSTEM_VARIABLES_ADMIN)。my.cnf 或使用 SET PERSIST (8.0+)。| 方式 | 語法 | 適用場景 |
|---|---|---|
| SET | SET var = expr; / SET @var = expr; | 單一變數賦值、純量運算 |
| SELECT ... INTO | SELECT col INTO @var FROM table WHERE ...; | 從查詢結果賦值(單行單列) |
| SELECT := | SELECT @var := col FROM table ...; | 會話變數行內累加、序號生成 |
CREATE PROCEDURE sp_get_max_id(OUT p_max_id INT)
BEGIN
SELECT MAX(id) INTO p_max_id FROM orders;
END;
v_ 前綴,會話變數用 @s_。BEGIN 之後、第一條執行語句之前。DEFAULT 0。SET @a = 1; PREPARE stmt FROM 'SELECT @a';。
DELIMITER //
CREATE PROCEDURE sp_order_stats(IN p_days INT, OUT p_total DECIMAL(10,2), OUT p_avg DECIMAL(10,2))
BEGIN
DECLARE v_start_date DATE;
SET v_start_date = DATE_SUB(CURDATE(), INTERVAL p_days DAY);
SELECT
COALESCE(SUM(amount), 0),
COALESCE(AVG(amount), 0)
INTO p_total, p_avg
FROM orders
WHERE create_time >= v_start_date;
END //
DELIMITER ;
-- 呼叫
CALL sp_order_stats(30, @total, @avg);
SELECT @total, @avg;
善用三類變數,能讓儲存過程邏輯更清晰、效能更優、維護更容易。