ODUDAT为空时SQL DELETE语句未按预期处理ODCDAT数据的技术排查请求
问题分析与解决方案
你的DELETE语句存在几个核心问题,导致它既没正确处理ODCDAT的场景,甚至核心判断逻辑也出现了颠倒:
- 比较符号完全搞反:你需要删除的是超过两个月的旧数据(日期早于当前日期减2个月),但原SQL用了
>,这会错误地删除近两个月的数据、保留旧数据,完全和需求相反! - 混淆空白字符串与SQL NULL:你说的ODUDAT“为空”应该是指全空白字符串(比如
' '),但COALESCE只识别SQL标准的NULL值,不会跳过空白字符串。所以当ODUDAT是空白时,COALESCE会直接取这个空白值,而非ODCDAT,导致后续比较完全失效。 - 冗余的CASE语句:
COALESCE(ODUDAT, ODCDAT, CASE...)中的CASE永远不会执行——因为ODCDAT是创建日期,不会为NULL,COALESCE会在前两个参数中就找到非NULL值。 - 字符串比较日期的隐患:直接用
MMDDYY格式的字符串比较日期,跨年度时会出错(比如'123123'(2023-12-31)字符串上大于'010124'(2024-01-01),但实际日期更早)。
修正后的SQL
我按照你的需求重新梳理了逻辑:
- 删除:有有效最后使用日期且该日期早于当前日期减2个月;或者无有效最后使用日期(空白/NULL)且创建日期早于当前日期减2个月。
- 保留:无最后使用日期但创建日期在近两个月内的。
DELETE FROM HERAPERM.SCRUBLITST WHERE -- 场景1:存在有效最后使用日期,且日期早于两个月前 (TRIM(ODUDAT) <> '' AND TO_DATE(TRIM(ODUDAT), 'MMDDYY') < CURRENT_DATE - 2 MONTHS) -- 场景2:无有效最后使用日期,但创建日期早于两个月前 OR (TRIM(ODUDAT) = '' AND TO_DATE(TRIM(ODCDAT), 'MMDDYY') < CURRENT_DATE - 2 MONTHS);
关键细节说明
- 用
TRIM()处理空白字符串:把全空白的ODUDAT转为空字符串,准确识别“未被使用”的场景。 - 用
TO_DATE()转换为日期类型:避免字符串比较的跨年度错误,让日期判断逻辑精准可靠。 - 拆分两种判断场景:清晰区分“有最后使用日期”和“无最后使用日期”的情况,完全匹配你的需求。
- 替换
>为<:正确对应“超过两个月的旧数据”的判断逻辑。
示例数据验证(假设当前日期为2021-06-01,两个月前为2021-04-01)
A210407001:ODUDAT空白,ODCDAT为040821(2021-04-08),晚于2021-04-01,会被保留。BYOD_00003:ODUDAT为021621(2021-02-16),早于2021-04-01,会被删除。DPI2194LO1:ODUDAT空白,ODCDAT为041221(2021-04-12),晚于2021-04-01,会被保留。DSLAMPORT1:ODUDAT为021521(2021-02-15),早于2021-04-01,会被删除。
建议先执行SELECT * FROM HERAPERM.SCRUBLITST搭配同样的WHERE条件,确认要删除的行符合预期后,再执行DELETE操作。
内容的提问来源于stack exchange,提问作者user3465081
相关产品推荐
相关产品推荐

