try_convert 能接住非法日期字符串是因为转换失败时返回 null 而非报错,与 convert 直接抛异常不同;它按语言设置解析字符串,推荐用样式码 120 避歧义,且不校验逻辑合理性(如闰年),null 表示不可信。

TRY_CONVERT 为什么能接住非法日期字符串
因为 TRY_CONVERT 在转换失败时返回 NULL,而不是直接报错——这和 CONVERT 的行为完全不同。CONVERT 遇到无法解析的日期(比如 '2023-02-30' 或 'abc')会立刻抛出 Conversion failed when converting date and/or time from character string. 错误,而 TRY_CONVERT 就像加了 try/catch 一样安静地返回 NULL,让你能继续做后续判断或默认值填充。
怎么用 TRY_CONVERT 判断并过滤非法日期
最常见场景是清洗脏数据:从文本列里提取有效日期。注意三点:
-
TRY_CONVERT(date, your_column)返回date类型,不是字符串,所以不能和字符串做=比较,要用IS NOT NULL - SQL Server 默认按当前语言设置解析字符串(如
'01/02/2023'在 us_english 是 2023-01-02,在 British English 是 2023-02-01),建议显式指定样式码避免歧义 - 样式码
120(ODBC 规范yyyy-mm-dd)最安全,103(dd/mm/yyyy)容易出错,慎用
示例:只取合法的 ISO 格式日期
SELECT * FROM logs WHERE TRY_CONVERT(date, log_date_str, 120) IS NOT NULL;
遇到 NULL 怎么补默认值或标记错误
别直接用 ISNULL(TRY_CONVERT(...), '1900-01-01') ——类型不匹配会报错。必须先保证类型一致:
- 想补默认日期:用
COALESCE(TRY_CONVERT(date, col), '1900-01-01')(COALESCE推导公共类型) - 想标记错误原因:配合
CASE WHEN TRY_CONVERT(...) IS NULL THEN 'invalid_date' ELSE 'ok' END - 想保留原字符串同时加转换结果:直接写
TRY_CONVERT(date, col, 120) AS parsed_date,结果列就是可空的date
TRY_CONVERT 处理日期时的隐藏陷阱
它不校验逻辑合理性。比如 TRY_CONVERT(date, '2023-02-30', 120) 返回 NULL(正确),但 TRY_CONVERT(date, '2023-00-01', 120) 也返回 NULL,而 TRY_CONVERT(date, '2023-13-01', 120) 同样是 NULL —— 这没问题;但要注意 TRY_CONVERT(date, '2023-02-29', 120) 在非闰年会返回 NULL,在闰年才成功。也就是说,它的“合法性”依赖实际日历规则,不是简单正则匹配。
如果你需要区分“格式错误”和“日期不存在”,仅靠 TRY_CONVERT 不够,得额外加 ISDATE()(已过时但仍有用)或用 PARSENAME + 字符串拆解做前置校验——不过多数业务场景,NULL 就代表“不可信”,已经够用了。











