Oracle SQL Loader中能否通过ctl文件按日期过滤要加载的数据行?
Oracle SQLLDR 控制文件过滤最新日期行解决方案
可以通过修改ctl控制文件实现行过滤,具体逻辑如下:
方案1:提前已知目标最新日期,直接修改ctl文件
SQLLDR支持WHEN子句实现行级过滤,你只需在原有控制文件基础上增加日期判断条件即可,修改后的ctl文件示例如下:
LOAD DATA -- 仅插入DATE字段等于目标最新日期的行,注意关键字DATE需要加双引号 WHEN "DATE" = '20211029' INSERT INTO TABLE SCHEMA.TBL_INTERFACE ( "ID" POSITION(001:008), "FIRSTNAME" POSITION(009:028), "LASTNAME" POSITION(029:048), "DATE" POSITION(049:058) )
如果你的业务固定每日加载当日日期的数据,直接把日期参数替换为当日的YYYYMMDD格式值即可。
方案2:动态提取文件内的最大日期过滤
如果需要自动识别当前接口文件内的最新日期,无法提前写死日期值,纯ctl单步无法实现(SQLLDR是逐行流式处理,没有预扫描全文件取最大值的能力),可以配合简单的前置脚本实现:
- 先通过脚本扫描接口文件,提取所有行的日期字段,排序后取最大值
- 把最大值动态替换到ctl文件的
WHEN条件中 - 执行SQLLDR加载
以Linux环境shell脚本为例,参考逻辑:
# 替换为你的实际接口文件路径 INTERFACE_FILE="./interface_data.txt" # 提取所有行的日期字段,取最大值 MAX_DATE=$(awk '{print substr($0,49,8)}' $INTERFACE_FILE | sort -nr | head -n 1) # 生成实际执行的ctl文件,把模板中的@MAX_DATE@替换为实际最大值 sed "s/@MAX_DATE@/${MAX_DATE}/g" ./template.ctl > ./run.ctl # 执行sqlldr sqlldr userid=你的数据库账号/密码@实例名 control=./run.ctl
对应的ctl模板文件template.ctl只需把方案1中的固定日期改为占位符即可:WHEN "DATE" = '@MAX_DATE@'
替代方案:临时表中转
如果不想引入额外脚本处理,也可以先把全量数据加载到一个结构和正式表一致的临时表,再通过SQL过滤出最大日期的数据插入正式表,逻辑更简单容错性更高,适合文件总数据量不是特别大的场景:
-- 插入正式表的SQL示例 INSERT INTO SCHEMA.TBL_INTERFACE SELECT * FROM SCHEMA.TBL_INTERFACE_TMP WHERE "DATE" = (SELECT MAX("DATE") FROM SCHEMA.TBL_INTERFACE_TMP);
内容的提问来源于stack exchange,提问作者Carlos_1988
相关产品推荐
相关产品推荐

