Oracle存储过程SQL插入需求:新增字段组合存在时不插入判断
解决Oracle存储过程中避免重复插入的问题
嘿,我来帮你搞定这个重复插入的问题!你的原查询已经能正常运行,现在只需要加个简单的判断逻辑,就能确保只有当NAME、E_ID、C_DATE、P_CHECK的组合在M_LOG表中不存在时,才会执行插入操作。
方案一:使用NOT EXISTS子句(基于你原语句改造)
这是最直接的改造方式,在原查询的WHERE条件里新增一个NOT EXISTS检查,过滤掉已经存在重复组合的记录:
INSERT INTO M_LOG(NAME, E_ID, C_DATE, STATUS, P_CHECK) SELECT MAX(ML.NAME), ML.E_ID, ML.C_DATE, 1, 'M Step_1' FROM F_LOG ML, DIR_LOG MD WHERE ML.NAME != MD.NAME AND ML.E_ID != MD.E_ID AND MD.C_DATE = LAST_DAY(TRUNC(SYSDATE)) -- 优化了日期处理,SYSDATE本身是日期类型,无需二次转换 AND NOT EXISTS ( -- 检查M_LOG中是否已有相同组合的记录 SELECT 1 FROM M_LOG ML_EXIST WHERE ML_EXIST.NAME = MAX(ML.NAME) AND ML_EXIST.E_ID = ML.E_ID AND ML_EXIST.C_DATE = ML.C_DATE AND ML_EXIST.P_CHECK = 'M Step_1' ) GROUP BY ML.E_ID, C_DATE;
几点说明:
NOT EXISTS子句会逐行检查源数据(你的分组查询结果)在M_LOG中是否有匹配的组合记录,只要存在就跳过该条插入。- 我把原语句里的
to_date(sysdate,'YYYYMMDD')改成了TRUNC(SYSDATE),因为SYSDATE本身就是日期类型,转成字符串再转回日期完全没必要,TRUNC(SYSDATE)能直接取当前日期的零点,逻辑和原语句一致但更高效。
方案二:使用MERGE语句(更直观的匹配逻辑)
如果后续可能需要扩展成“存在则更新,不存在则插入”的场景,MERGE语句会更合适,逻辑也更清晰:
MERGE INTO M_LOG TARGET USING ( -- 原查询作为源数据,提前定义别名方便后续匹配 SELECT MAX(ML.NAME) AS NAME, ML.E_ID, ML.C_DATE, 1 AS STATUS, 'M Step_1' AS P_CHECK FROM F_LOG ML, DIR_LOG MD WHERE ML.NAME != MD.NAME AND ML.E_ID != MD.E_ID AND MD.C_DATE = LAST_DAY(TRUNC(SYSDATE)) GROUP BY ML.E_ID, C_DATE ) SOURCE -- 匹配重复组合的条件 ON (TARGET.NAME = SOURCE.NAME AND TARGET.E_ID = SOURCE.E_ID AND TARGET.C_DATE = SOURCE.C_DATE AND TARGET.P_CHECK = SOURCE.P_CHECK) -- 当没有匹配到重复记录时,执行插入 WHEN NOT MATCHED THEN INSERT (NAME, E_ID, C_DATE, STATUS, P_CHECK) VALUES (SOURCE.NAME, SOURCE.E_ID, SOURCE.C_DATE, SOURCE.STATUS, SOURCE.P_CHECK);
这个方案把“检查重复”和“插入”逻辑整合在一起,可读性更强,也方便后续维护。
内容的提问来源于stack exchange,提问作者Marcus
相关产品推荐
相关产品推荐

