MySQL中||默认是逻辑或而非字符串拼接,需启用PIPES_AS_CONCAT模式;CONCAT遇NULL返回NULL,CONCAT_WS跳过NULL;跨库兼容推荐CONCAT但需处理NULL差异。
MySQL 里用
拼字符串,为什么结果是 0 或 NULL?
因为默认情况下,mysql 的
不是字符串拼接,而是逻辑或运算符。只有当 sql 模式启用了
,
才等价于
。
常见错误现象:
返回
(两个非空字符串转布尔都是 TRUE,TRUE OR TRUE = 1?不对——实际是先转数字失败→0),或者在严格模式下直接报错。
检查当前模式:
,看是否含
临时启用(当前会话):
不推荐全局改,尤其在多应用共用实例时,可能破坏依赖标准行为的旧逻辑
和
的 NULL 处理差异
遇到任意参数为
,整条结果就变成
;而
(WS = With Separator)只跳过
参数,不影响其余部分。
使用场景:拼接用户姓名字段,
可能为空,用
一空全空;换成
就自然省略空段。
→
→
的第一个参数是分隔符,不能为
,否则整个结果为
性能上
真的比
快吗?
在启用了
的前提下,两者执行计划、底层处理路径几乎一致,性能差异可忽略——不是语法糖快,是“根本没额外开销”。真正影响性能的是拼接内容本身:字段长度、字符集转换、是否触发隐式类型转换。
容易踩的坑:
中
是 INT,MySQL 会把整行记录的
字段也转成 same charset + collation 再拼,若
是 utf8mb4 而连接默认字符集是 latin1,就会悄悄触发转换,拖慢查询。
显式转码更可控:
避免混合数值与字符串直接拼接,尤其在 WHERE 或 ORDER BY 中参与计算时
高并发拼接长文本(如日志聚合)时,优先考虑应用层做,别压给 MySQL 字符串函数
PostgreSQL / Oracle / SQL Server 怎么看?
别套用 MySQL 经验:
在 PostgreSQL 和 Oracle 中原生就是字符串拼接,无需设模式;SQL Server 则完全不支持
,必须用
(且对
更敏感)或
(SQL Server 2012+)。
跨数据库写法最稳的是
,但要注意:MySQL
不接受
,而 SQL Server 和 PostgreSQL 的
会自动跳过
—— 同一个函数,在不同库行为不一致。
MySQL:
→
SQL Server:
→
真要移植,要么统一用
做兜底,要么干脆别拼,让应用层处理
字符集、NULL 行为、跨库兼容性这三块,改一行拼接代码就可能漏掉两处隐式陷阱。
||||pipes_as_concat||concat()SELECT 'a' || 'b';0SELECT @@sql_mode;PIPES_AS_CONCATSET sql_mode = CONCAT(@@sql_mode, ',PIPES_AS_CONCAT');CONCAT()CONCAT_WS()CONCAT()NULLNULLCONCAT_WS()NULLmiddle_nameCONCAT(first, ' ', middle, ' ', last)CONCAT_WS(' ', first, middle, last)CONCAT('a', NULL, 'c')NULLCONCAT_WS('-', 'a', NULL, 'c')'a-c'CONCAT_WS()NULLNULL||CONCAT()PIPES_AS_CONCATCONCAT(id, name)idnamenameCONCAT(CAST(id AS CHAR), name)||||+NULLCONCAT()CONCAT()CONCAT()NULLCONCAT()NULLCONCAT(NULL, 'a')NULLCONCAT(NULL, 'a')'a'COALESCE(col, '')