MySQL 字符串函数必须用单引号包裹字面量
MySQL 不接受双引号作为字符串字面量的定界符(除非 SQL_MODE 启用了
ANSI_QUOTES),否则会报错
ERROR 1054 (42S22): Unknown column 'xxx' in 'field list'。这是因为 MySQL 默认把双引号当成标识符(如列名、表名)处理,而非字符串。
实操建议:
所有字符串参数统一用单引号,例如:CONCAT('Hello', ' ', 'World')
若需在字符串中包含单引号,用两个单引号转义:'O''Reilly'避免依赖
ANSI_QUOTES模式,它会让
"name"被解析为字段名,和多数 ORM 或迁移工具行为冲突
LEFT、SUBSTRING 等截取函数的起始位置从 1 开始计数
不同于 Python 或 JavaScript 的 0-based 索引,MySQL 所有基于位置的字符串函数(
LEFT、
SUBSTRING、
MID、
LOCATE)均以 1 为第一个字符的位置。传入 0 会返回空字符串或 NULL,不是“从开头”——这是最常踩的坑。
实操建议:
SUBSTRING('abcde', 1, 3) → 'abc';
SUBSTRING('abcde', 0, 3) → ''(空字符串) 想从第 n 个字符开始取,直接写
n,不要减 1;
LOCATE('x', col) 返回值也从 1 起算
用 INSTR(str, substr)可替代
LOCATE,语序相反但同样 1-based
CONCAT 函数遇到 NULL 直接返回 NULL,不自动跳过
CONCAT是严格模式:只要任一参数为
NULL,整个结果就是
NULL。这和
CONCAT_WS(带分隔符版本)不同,后者会忽略
NULL参数。
实操建议:
拼接可能为 NULL 的字段时,优先用CONCAT_WS('', col1, col2, col3),它自动跳过 NULL
必须用 CONCAT时,配合
IFNULL或
COALESCE显式兜底:
CONCAT(IFNULL(name, ''), ' ', IFNULL(surname, ''))注意
CONCAT_WS的第一个参数是分隔符,不能省略;传空字符串
''等效于无分隔拼接
大小写敏感性取决于列的 collation,不是函数本身
UPPER、
LOWER、
REPLACE这些函数本身不决定比较逻辑;是否区分大小写,完全由字段定义的
COLLATION决定(比如
utf8mb4_0900_as_cs是区分大小写的,而
utf8mb4_0900_ai_ci是不区分且带重音忽略的)。
实操建议:
执行SHOW FULL COLUMNS FROM table_name LIKE 'col_name';查看当前列的
Collation若需强制大小写敏感匹配,可在 WHERE 中加
BINARY:
WHERE BINARY name = 'John'
REPLACE(str, from_str, to_str)是逐字节替换,不支持正则;需要正则替换得用
REGEXP_REPLACE()(MySQL 8.0+)
SELECT name, UPPER(name) AS upper_name, REPLACE(LOWER(name), 'a', 'x') AS replaced_lower FROM users WHERE BINARY name = 'Alice';字符串处理真正难的不是记函数名,而是时刻意识到:MySQL 的“字符串”背后绑着字符集、排序规则、NULL 传播规则三重上下文。漏掉任意一个,
CONCAT就可能突然变
NULL,
SUBSTRING就会切错位置,
WHERE就会查不到本该匹配的数据。
