從變數分類、作用域、賦值語法到實戰案例,完整解析 MySQL 使用者自訂會話變數 (@var) 在解決主從同步延遲導致計數器不準問題中的應用。
| 大類 | 子類 | 作用域 | 生命週期 | 典型用途 |
|---|---|---|---|---|
| 使用者自訂 | 局部變數 | BEGIN...END 區塊 | 存儲過程調用期間 | 存儲過程邏輯暫存 |
| 會話變數 (@var) | 當前連線 | 連線斷開釋放 | 跨 SQL 傳值、計數器 | |
| 系統變數 | 會話變數 | 當前連線 | 連線期間 | 調整當前連線行為 (sql_mode 等) |
| 全域變數 | 全伺服器 | 啟動至關機 (重啟失效) | 伺服器級配置 |
SET @a = 1, @b = 2;
SET @c := @a + @b; -- 非 SET 語句必須用 :=
SELECT @c; -- 3
SELECT @a;
SELECT @@session.var_name; -- 系統會話變數用 @@
SHOW SESSION VARIABLES LIKE '%var%';
-- ❌ 不穩定
SELECT @a, @a:=@a+1 FROM t;
-- ✅ 分離
SET @a = @a + 1;
SELECT @a;
原因:運算順序未定義,且回傳型別由語句開始時決定-- ❌ HAVING 引用同 SELECT 定義的別名失效
SELECT (@aa:=id) AS a, (@aa+3) AS b FROM t HAVING b=5;
-- 原因:HAVING 執行時 @aa 仍為上一語句結果
-- 存儲過程 / 直接 SQL
UPDATE super_topic_counter
SET counter = @counter := counter + 1
WHERE uid = ? AND topic_id = ? AND action_type = ?;
SELECT @counter; -- 取得遞增後的新值,用於積分計算
使用者自訂會話變數儲存在 伺服器端連線執行緒記憶體 中 (非客戶端),連線斷開自動釋放。這保證了同一連線內多語句間的可見性。