MySQL 使用 CONCAT() 函數進行字串串接,而非 ||(PostgreSQL/Oracle)或 +(SQL Server)。此差異常導致跨資料庫遷移時的語法錯誤,需特別注意。
-- 在 aa 表 name 欄位前加上 'x'
UPDATE aa SET name = CONCAT('x', name);
-- 批次更新會員卡號前綴
UPDATE member SET card = CONCAT('00', card);
| 函數 | 語法 | 行為差異 | 適用場景 |
|---|---|---|---|
CONCAT |
CONCAT(str1, str2, ...) |
任一參數為 NULL → 結果為 NULL | 確定無 NULL 值的串接 |
CONCAT_WS |
CONCAT_WS(separator, str1, str2, ...) |
自動跳過 NULL 參數,用分隔符連接非 NULL 值 | 多欄位組合、可能含 NULL |
GROUP_CONCAT |
GROUP_CONCAT(expr ORDER BY ... SEPARATOR ',') |
聚合函數,將群組內值串成單一字串 | 一對多關聯查詢、標籤聚合 |
-- 1. 多欄位組合地址(跳過 NULL)
UPDATE users SET full_address = CONCAT_WS(' ', city, district, street, detail);
-- 2. 生成唯一代碼:前綴 + 零填充 ID + 隨機碼
UPDATE products SET sku = CONCAT('PRD-', LPAD(id, 8, '0'), '-', SUBSTRING(MD5(RAND()), 1, 4));
-- 3. JSON 字串組裝(MySQL 5.7+ 建議用 JSON 函數)
UPDATE settings SET config_json = CONCAT('{"theme":"', theme, '","lang":"', lang, '"}');
WHERE CONCAT(col1, col2) = 'value' 會導致全表掃描。改用 WHERE col1 = 'val1' AND col2 = 'val2' 或建立虛擬欄位/函數索引(8.0+)LIMIT 10000)、低峰期執行、監控 Innodb_row_lock_waitsSET NAMES utf8mb4)、表字元集、資料實際編碼三者一致,避免串接後亂碼max_allowed_packet 限制:超長字串串接可能觸發「Packet too large」錯誤,需調大該參數| 資料庫 | 串接運算子/函數 | NULL 處理 |
|---|---|---|
| MySQL | CONCAT() / CONCAT_WS() |
CONCAT 遇 NULL 回傳 NULL |
| PostgreSQL | || / CONCAT() (9.1+) |
|| 遇 NULL 回傳 NULL,CONCAT 忽略 NULL |
| Oracle | || / CONCAT() (僅兩參數) |
|| 遇 NULL 回傳 NULL |
| SQL Server | + / CONCAT() (2012+) |
+ 遇 NULL 回傳 NULL,CONCAT 忽略 NULL |
| SQLite | || |
遇 NULL 回傳 NULL |
掌握 CONCAT 系列函數細節,能避開跨資料庫遷移陷阱,也能寫出更健壯、效能更佳的字串操作 SQL。記住:查詢條件避免對欄位使用函數,更新操作則善用 CONCAT_WS 處理潛在 NULL 值。