存储过程中如何按条件替换YesterdayDate为TodayDate且不破坏原有逻辑
实现方案
方案1:最小侵入式改造(仅新增3行代码,原有逻辑零修改)
这个方案不需要改动你现有<do_some_stuff>里的差值计算逻辑,也不用调整游标返回的字段结构,完全兼容原有功能。
改造逻辑:
- 新增一个变量存储实际生效的对比日期,先校验昨日数据集是否存在,存在就用入参
YesterdayDate,不存在就用TodayDate - 仅把游标里的
YESTERDAY.DATASET_DATE过滤条件替换成这个变量即可
修改后的完整代码如下:
CREATE OR REPLACE function DO_STUFF (TodayDate date, YesterdayDate date) return integer is status integer; -- 新增变量:存储实际生效的对比日期 v_effective_yesterday date; BEGIN -- 新增校验逻辑:判断昨日数据集是否存在 SELECT CASE WHEN COUNT(1) >0 THEN YesterdayDate ELSE TodayDate END INTO v_effective_yesterday FROM TableName WHERE DATASET_DATE = YesterdayDate; DECLARE CURSOR c_stuff IS SELECT <several_fields> FROM TableName TODAY LEFT JOIN TableName YESTERDAY ON TODAY.KEY1 = YESTERDAY.KEY1 WHERE TODAY.DATASET_DATE = TodayDate -- 这里替换为实际生效的对比日期即可 AND YESTERDAY.DATASET_DATE = v_effective_yesterday ORDER BY TODAY.KEY1 ASC; BEGIN FOR r_lines IN c_stuff LOOP <do_some_stuff> END LOOP; END; COMMIT; STATUS := 0; return status; END /
方案2:纯SQL层改造(无需新增PLSQL变量)
如果你不想新增PLSQL变量,也可以直接在游标查询里通过SQL逻辑实现日期判断,不需要额外的校验代码,改动同样很小:
仅需要把游标里的YESTERDAY.DATASET_DATE = YesterdayDate条件替换为下面的逻辑即可:
AND YESTERDAY.DATASET_DATE = NVL( (SELECT MAX(DATASET_DATE) FROM TableName WHERE DATASET_DATE = YesterdayDate), TodayDate )
注意事项
两种方案都保留了你原有的双日期关联逻辑,<do_some_stuff>里读取YESTERDAY别名字段的代码完全不需要修改:
- 当昨日数据集存在时,逻辑和改造前完全一致,不会影响原有正常场景的计算结果
- 当昨日数据集不存在时,会自动用今日数据集和自身做关联,差值计算结果为0,符合你预期的规避错误数据的需求
内容的提问来源于stack exchange,提问作者Daniel Corsi
相关产品推荐
相关产品推荐

