使用sqlldr加载数据仅导入每行首字符的技术求助
嘿,这种情况我碰过好多次了,基本上都是控制文件的配置踩坑了,结合你的场景(AIX上Oracle 12.1、单列可变长文本、每行一条记录),给你几个针对性的排查和解决步骤:
1. 先检查你的控制文件(.ctl)
默认情况下,如果没明确指定字段长度,SQL*Loader会默认只读取1个字符,这就是你只看到第一个字符被导入的核心原因。你需要在控制文件里明确指定字段的最大长度,同时把换行符设为记录终止符(因为你是每行对应一条记录)。
给你一个适配你场景的控制文件示例(假设你的表叫MY_TABLE,列名是MY_COLUMN):
LOAD DATA INFILE '你的数据文件名.txt' INTO TABLE MY_TABLE TRUNCATE -- 这里根据你的需求选择:INSERT/APPEND/REPLACE/TRUNCATE,TRUNCATE会清空表再加载 FIELDS TERMINATED BY '\n' -- 用换行符作为每条记录的结束标记 (MY_COLUMN CHAR(10)) -- 对应你测试集的10字符限制,要是实际数据更长可以改大,比如CHAR(100)
如果你的数据行长度不确定,Oracle 12.1也支持CHAR(MAX)来读取整行内容,不过建议还是设一个合理的最大长度更稳妥。
2. 确认数据文件的换行符格式
AIX系统默认用LF(\n)作为换行符,但如果你的数据文件是在Windows环境生成的,可能带有CRLF(\r\n)格式的换行符,这会导致SQL*Loader误判记录终止符。你之前用od -c查看数据时,可以留意每行结尾的字符:
- 如果是
\n就没问题; - 如果是
\r\n,要么把控制文件里的终止符改成'\r\n',要么用sed 's/\r$//' 原文件.txt > 转换后文件.txt把文件转成AIX兼容格式(AIX上如果没有dos2unix工具的话,这个sed命令就能搞定)。
3. 检查表列的定义
别忽略了表本身的问题!如果你的目标列被定义成了CHAR(1)或者VARCHAR2(1),那肯定只能装下第一个字符。用这条SQL查一下表结构:
DESC MY_TABLE;
要是列长度不够,赶紧修改:
ALTER TABLE MY_TABLE MODIFY MY_COLUMN VARCHAR2(10); -- 长度可以根据实际需求调整
4. 用TEST参数快速验证控制文件
不想浪费时间加载真实数据测试的话,可以用SQL*Loader的TEST=YES参数来模拟加载过程,看看会不会报错或者输出异常统计:
sqlldr userid=你的用户名/密码@数据库实例 control=你的控制文件.ctl TEST=YES
这个命令会输出模拟的加载结果,能帮你快速定位配置问题。
额外小技巧
如果你的数据文件里有空白行,或者行首/行尾带有多余空格,可以在控制文件里添加TRAILING NULLCOLS和TRIM选项来处理:
LOAD DATA INFILE '你的数据文件名.txt' INTO TABLE MY_TABLE TRUNCATE FIELDS TERMINATED BY '\n' TRAILING NULLCOLS -- 自动处理空白行 (MY_COLUMN CHAR(10) TRIM BOTH) -- 去掉字段前后的空格
内容的提问来源于stack exchange,提问作者cluhendrix

