str_to_date静默返回null主因是格式串与字符串不匹配,需检查分隔符、年份位数、补零规则、全角字符、空格及混合格式,并用coalesce多格式回退或预处理统一结构。

STR_TO_DATE 返回 NULL 却不报错,怎么确认是格式不匹配
它根本不会报错,只静默返回 NULL,这是最易被忽略的陷阱。查不到数据、字段批量变空,往往就卡在这儿。
先用 SELECT 直接测单条:
SELECT STR_TO_DATE('2023/05/12', '%Y-%m-%d');
结果是 NULL?说明格式串和字符串对不上——不是函数坏了,是模板写错了。
- 检查分隔符:字符串用
/,格式串就得写'%Y/%m/%d',不能写成-或空格 - 检查年份位数:
%Y对应四位(如2023),%y对应两位(如23),混用直接失败 - 检查月份/日期是否补零:
'2023-5-1'不能用'%Y-%m-%d',得用'%Y-%c-%e'(但更建议先用REPLACE补零)
输入含中文、斜杠、空格时,格式串必须一字不差
从 Excel 或网页粘贴的日期常带中文或全角字符,比如 '2023年05月12日' 或 '2023/05/12'(注意这个是全角斜杠)。MySQL 会逐字符比对,差一个字就失败。
-
STR_TO_DATE('2023年05月12日', '%Y年%m月%d日')✅ -
STR_TO_DATE('2023/05/12', '%Y/%m/%d')✅(全角斜杠必须原样写) -
STR_TO_DATE(' 2023-05-12 ', '%Y-%m-%d')❌(首尾空格必须先TRIM()) -
STR_TO_DATE('12/May/2023', '%d/%b/%Y')✅(%b是小写英文缩写,May不行,may才行)
批量处理前没验证数据混合格式,一条错全盘空
CSV 导入或日志解析时,同一列里可能混着 '2023-05-12'、'12/05/2023'、'20230512' 多种格式。单靠一个 STR_TO_DATE 格式串不可能全覆盖。
- 先定位问题数据:
SELECT str_col FROM t WHERE STR_TO_DATE(str_col, '%Y-%m-%d') IS NULL; - 再用
COALESCE尝试多格式 fallback:COALESCE(STR_TO_DATE(s, '%Y-%m-%d'), STR_TO_DATE(s, '%d/%m/%Y'), STR_TO_DATE(s, '%Y%m%d')) - 如果格式差异太大(比如有
'May 12, 2023'),就得先用REPLACE统一结构,再转
在 INSERT 或 LOAD DATA 中漏掉变量初始化,导致值污染
用 LOAD DATA INFILE 导入时,用户变量(如 @date_str)会跨行保留。上一行转换失败留下旧值,下一行没读到新值,就拿错的字符串去解析。
- 必须显式初始化:
@date_str := NULLIF(@date_str, '') - 完整写法示例:
SET created_at = STR_TO_DATE(@date_str := NULLIF(@date_str, ''), '%Y-%m-%d') - INSERT ... SELECT 场景下,也要先
WHERE STR_TO_DATE(col, fmt) IS NOT NULL过滤,避免把NULL插进非空字段触发报错
'2023-02-30' 这种非法日期也默默接受——直到某天业务逻辑崩了才回头翻日志。











