sqlldr因NAME列含2个以上双引号加载失败求助
我之前也遇到过完全一样的问题——SQL*Loader的OPTIONALLY ENCLOSED BY '"'规则会把字段内的单个双引号误判为字段结束标记,直接导致解析失败,只有格式“合规”的记录才能插入。下面给你两种可行的解决思路,你可以根据是否能修改数据文件来选择:
方法一:修改数据文件的双引号为转义格式(推荐如果有权限改数据的话)
SQL*Loader默认要求字段内的双引号必须用两个连续双引号来转义,这样它才会把这个双引号当作字段内容的一部分,而不是字段边界。
比如把你的data.txt里的原内容:
""start with double quote " "end with double quote "" "double quote " in the middle "
修改为:
""start with double quote "" ""end with double quote """" ""double quote "" in the middle ""
(把内容里所有单个的双引号都替换成两个连续的双引号)
之后保留你原来的控制文件,就能正常加载所有记录了——现在SQL*Loader会正确识别转义后的双引号,不会再误判字段结束位置。
方法二:修改控制文件,跳过默认的引号解析(如果不能改数据的话)
如果没法修改data.txt的内容,那我们可以调整控制文件逻辑,直接读取字段内容并手动处理引号:
场景1:每条记录就是一行完整的name值(无逗号分隔)
如果你的data.txt里每一行对应一条employee记录的name字段,不管内容里有双引号、逗号还是其他字符,那可以简化控制文件,直接读取整行内容:
load data infile '/tmp/swetabh/data.txt' into table employee truncate TRAILING NULLCOLS ( name CHAR(4000) -- 直接读取整行作为name字段的内容 )
场景2:字段用逗号分隔,但name字段可能包含逗号和双引号
如果你的数据确实是用逗号作为字段分隔符(哪怕只有name这一个字段),那可以去掉OPTIONALLY ENCLOSED BY '"'配置,然后用TRIM函数去掉字段前后的双引号,同时保留字段内的所有双引号:
load data infile '/tmp/swetabh/data.txt' into table employee truncate fields terminated by "," TRAILING NULLCOLS ( name CHAR(4000) "TRIM('"' FROM :name)" )
这个方法会自动清理字段首尾的双引号,同时完整保留内容里的所有双引号和其他字符,不管数量多少。
验证加载结果
修改完控制文件或数据文件后,重新执行你的sqlldr命令:
sqlldr userid=xxx/xxx@xxxx control=/tmp/swetabh/control.txt log=/tmp/swetabh/control.log bad=/tmp/swetabh/bad.txt readsize=2000000000 bindsize=2000000000
查看control.log文件确认加载成功,同时检查bad.txt里没有新增的失败记录,就说明所有记录都正常插入了。
内容的提问来源于stack exchange,提问作者swet

