
MySQL 中 find_in_set 报错通常不抛出明确的「函数不存在」类错误,而是表现为:NULL 返回值、空结果、或直接报错如 Incorrect argument to FIND_IN_SET。后者多见于 MySQL 8.0.17+ 版本——当第一个参数(要查找的字符串)为 NULL,或第二个参数(逗号分隔字符串)不是合法字符串(如为数字、NULL、JSON 值)时触发。
这不是语法错误,但属于高频误用场景:该函数严格匹配子串,且**不支持前导/尾随空格、大小写敏感(取决于列 collation)、也不支持嵌套或通配符**。
find_in_set('a', 'a,b,c') ✅ 返回 1find_in_set(' a', 'a,b,c') ❌ 返回 0(开头空格导致完全不匹配)find_in_set('A', 'a,b,c') 取决于字段排序规则,若为 utf8mb4_0900_as_cs 则返回 0find_in_set('ab', 'a,ab,abc') ✅ 返回 2;但 find_in_set('a', 'ab,ac') ❌ 返回 0(不是子串搜索)如果字段实际存的是 JSON 数组(如 ["a","b","c"]),硬套 find_in_set 会失败,因为它的第二个参数必须是纯逗号分隔字符串,不能带方括号或引号。
JSON_CONTAINS(col, '"a"')(注意引号转义)col REGEXP '(^|,)admin(,|$)'
find_in_set 全表扫描,改用关联中间表或生成列 + 索引MySQL 慢日志或通用日志里不会直接标记 “find_in_set 错误”,需结合上下文判断:
general_log = ON,查日志中对应 SQL 是否传入了 NULL 或非字符串值WHERE col IS NOT NULL AND col != '' AND find_in_set('x', col)
SELECT col, LENGTH(col), DUMP(col) FROM tbl WHERE ... 检查字段真实内容(DUMP() 能暴露不可见字符)join(',') 后未 trim —— PHP 的 implode(',', $arr) 若含空值会产生 ,,,导致 find_in_set 行为异常INT)转成字符串传给 find_in_set,但一旦该字段为 NULL,整个函数就返回 NULL,而 WHERE NULL 恒为 false —— 这种情况在日志里只体现为“无结果”,没有任何报错提示。