文章目錄
- MySQL交換數據庫表中兩列的值(額外的知識)
- 為防止后面有疑問,提前解釋為什么需要 `$$` ?
- 第一版需求
- 第二版需求
- 第三版需求
-
- 注意事項:
- 存在的嚴重問題
- 最終版
-
- 關鍵修復說明:
- 完整測試場景:
- 額外建議(如果需要顯式處理NULL):
- COALESCE函數
- 業務中出現的問題
MySQL交換數據庫表中兩列的值(額外的知識)
UPDATE your_table t1, your_table t2
SET t1.column1 = t2.column2,t1.column2 = t2.column1
WHERE t1.id = t2.id
AND your_condition;
以下操作需要注意:確保MySQL用戶有創建觸發器的權限(TRIGGER權限);注意避免觸發器和業務邏輯的遞歸調用(如:訂單表的更新又觸發其他觸發器)
為防止后面有疑問,提前解釋為什么需要 $$
?
-
默認分隔符問題:
-
MySQL 默認使用分號
;
作為語句結束符 -
但觸發器/存儲過程等包含多個 SQL 語句,內部也有
;
-
如果直接用
;
,MySQL 會在第一個;
就認為語句結束
-
-
解決方案
DELIMITER $$ -- 將結束符臨時改為 $$CREATE TRIGGER ... -- 多行觸發器定義 BEGIN...; -- 內部語句仍用分號...; END$$ -- 用 $$ 表示整個觸發器結束DELIMITER ; -- 恢復默認分隔符
-
具體解析
DELIMITER $$ -- 告訴MySQL:"從現在開始,用$$作為語句結束符"CREATE TRIGGER... -- 開始定義觸發器 BEGIN...; -- 觸發器內部語句(有分號但不會立即執行)...; END$$ -- 用$$表示整個觸發器定義結束DELIMITER ; -- 恢復默認結束符(分號)
-
類比理解
場景 類比 默認分號 ;
句號 .
(結束一個完整句子)創建觸發器 寫一段包含多個句子的段落 DELIMITER $$
聲明:“接下來我要說一大段話,直到聽到$$才算結束” END$$
“我說完了($$)” DELIMITER ;
“現在恢復,句號表示句子結束” -
重要提示:
-
$$
不是關鍵字,可以替換成其他符號(常用//
或%%
)DELIMITER // CREATE TRIGGER ... BEGIN ... END// DELIMITER ;
-
必須成對出現:
開始:
DELIMITER 自定義符號
結束:
自定義符號
+DELIMITER ;
-
只在命令行或腳本中需要:
-
在 MySQL Workbench 等圖形工具中通常會自動處理
-
但在 SQL 腳本或命令行中必須顯式使用
-
簡單說:
$$
就是個"臨時盾牌",保護觸發器內部的;
不被誤認為是結束符,確保整個觸發器被完整解析。 -
第一版需求
需要監聽訂單商品表的中申請中數量的更新,如果更新的值不為0,則需要修改對應訂單表中訂單的remark字段的值為申請售后中
;
DELIMITER $$CREATE TRIGGER after_order_item_update
AFTER