SQL*Loader加载中途退出返回0 数据截断、行数统计异常排查
SQL*Loader静默中断、字段截断问题排查方案
这个问题和数据库字段长度无关,核心是SQL*Loader没有读完整个数据文件就提前终止了,按以下优先级排查即可:
1. 第一优先级:排查数据文件中的嵌入式EOF字符
进程返回码0、无数据报错、读取行数固定停在2423295、字段随机截断,是SQLLoader读到文件结束控制字符的典型表现*
- 用十六进制编辑器打开目标ELF数据文件,直接跳转到偏移量对应第2423295行的位置,查找十六进制值为
0x1A的Ctrl+Z(SUB替换字符)。你用的12.1.0.1.0版本SQL*Loader默认将这个字符识别为文件终止标记,读到就直接停止后续所有读取操作,不会抛任何错误,进程正常退出返回0,和你描述的现象完全吻合。 - 你提到的字段截断问题,基本可以确定是这个
0x1A字符刚好出现在该字段值的ANG文本之后,SQL*Loader读到这里直接截断当前字段、结束行解析,后续文件内容完全不处理,所以数据库里只存到ANG位置。
2. 第二优先级:核查控制文件解析配置
从你贴的日志看当前Continuation: none specified,也就是没配置跨行续读规则,再核对以下配置项:
- 检查控制文件里出问题的字段是否用了固定位置
POSITION参数,如果POSITION定义的长度小于字段实际长度,会直接截断内容,但这类问题不会导致全文件读取行数减半,仅作为排除项检查。 - 核对行终止符配置:如果数据文件是Windows平台生成(行终止符为
\r\n),但SQL*Loader运行在Linux/Unix平台默认按\n识别行,会出现解析错位,但这类问题通常会伴随大量数据格式错误,和你日志里0行数据错误的现象不符,优先级较低。 - 检查缓冲区参数:你当前日志显示bind array最大上限为2097152字节(2MB),如果单行数据长度极端大可能触发缓冲区不足,但12c版本遇到这类问题会抛出明确错误,不会静默退出,优先级最低。
3. 第三优先级:排查版本已知bug
你使用的12.1.0.1.0是Oracle 12c的首个初始版本,存在多个已知的静默读取中断bug:
- 该版本在读取包含多字节字符(中文、全角符号、特殊扩展ASCII字符)的变长字段时,存在字符边界识别错误,可能误判行长度、提前终止读取,不会返回非0错误码。
- 如果排查完文件本身没有特殊控制字符,可以换用12.1.0.2及以上补丁版本、或者11gR2版本的SQL*Loader客户端加载同一份文件,验证是否能读取全部5505501行数据。
快速验证手段
不需要跑全量加载,两个小测试就能快速定位:
- 找到第2423295行附近的可疑
0x1A字符删除后,加载小范围数据,看读取行数是否恢复正常、字段是否还会截断。也可以先在控制文件头部添加READSIZE=10485760、STREAMSIZE=10485760把读写缓冲区调到10MB,加上BYTEORDERMARK CHECK检查文件BOM头,排除缓冲区和编码问题。 - 把那条被截断的记录单独抽出来做成小测试文件加载,如果能复现截断问题,直接查看这条测试记录的十六进制内容,就能找到隐藏的控制字符。
后续加载任务建议配置
DISCARD=<自定义文件名>.dsc,所有不匹配WHEN子句的记录都会写入该文件,大幅降低解析类问题的排查成本。
内容的提问来源于stack exchange,提问作者Venkatesh R
相关产品推荐
相关产品推荐

