PostgreSQL中Varchar转Date遇31/09/2024报错,求解决办法
问题原因与解决方案
错误根源
- Null判断逻辑错误:原语句中
WHEN documento = null永远不会触发,SQL里判断字段是否为Null必须用IS NULL。 - 无效日期未拦截:
31/09/2024是无效日期(9月只有30天),但你的CASE逻辑仅校验了格式是否包含斜杠,未验证日期本身的有效性,导致TO_Date转换时抛出“超出范围值”错误。
修正后的查询语句(分数据库示例)
MySQL 8.0+
利用TRY_CAST函数自动处理无效日期,转换失败时返回Null:
select id, documento, case WHEN documento IS NULL OR documento = '' THEN null WHEN documento NOT LIKE '__/__/____' THEN null -- 严格匹配两位日/月、四位年的格式 ELSE TRY_CAST(documento AS DATE FORMAT 'DD/MM/YYYY') end as dt_scadenza_documento_id from tab;
PostgreSQL
使用TRY_TO_DATE函数直接容错无效日期:
select id, documento, case WHEN documento IS NULL OR documento = '' THEN null WHEN documento !~ '^\d{2}/\d{2}/\d{4}$' THEN null -- 正则校验确保全数字格式 ELSE TRY_TO_DATE(documento, 'DD/MM/YYYY') end as dt_scadenza_documento_id from tab;
Oracle
先用VALIDATE_CONVERSION校验日期有效性,再执行转换:
select id, documento, case WHEN documento IS NULL OR documento = '' THEN null WHEN NOT REGEXP_LIKE(documento, '^\d{2}/\d{2}/\d{4}$') THEN null WHEN VALIDATE_CONVERSION(documento AS DATE, 'DD/MM/YYYY') = 0 THEN null -- 校验日期是否合法 ELSE TO_DATE(documento, 'DD/MM/YYYY') end as dt_scadenza_documento_id from tab;
关键优化点
- 替换
= null为IS NULL,正确识别Null值 - 用更严格的格式校验(下划线/正则)替代模糊的
LIKE '%%/%%/%%%%',过滤非标准格式的字符串 - 引入日期容错机制,避免无效日期导致的转换报错
内容的提问来源于stack exchange,提问作者Francesco Portgas D. Cottardo
相关产品推荐
相关产品推荐

