SQL*Loader加载带特殊字符的管道分隔CSV至EMPLOYEE表报错求助
解决SQL*Loader加载带转义字符和内嵌分隔符CSV的问题
问题根源分析
第三条记录加载失败的核心原因有两个:
- 字段
EMPNAME_ADDRESS的闭合双引号缺失,导致SQL*Loader无法识别该字段的结束位置,一直找不到下一个分隔符|; - 字段内使用了
\"作为转义双引号,但SQL*Loader默认不支持反斜杠转义,同时字段内还内嵌了分隔符|,当前控制文件的配置无法正确解析这种复杂格式。
分步修改方案
1. 修正CSV源文件的格式问题
首先补全第三条记录末尾的闭合双引号,确保字段边界清晰:
EMPID|EMPNAME_ADDRESS|SALARY|GRADE 123|Rams Hyd|1000|A1 124|Sand MUM|2,000|A2 125|"PRASANNA qwer trasf\"501 advv vvd, qee ggg\trfe \411005 THE"|3,00,000|A3
如果业务场景允许,推荐把字段内的\"改成SQLLoader默认支持的双引号转义格式"",兼容性会更好。*
2. 更新SQL*Loader控制文件
针对当前的CSV格式,修改控制文件如下:
LOAD DATA INSERT INTO TABLE EMPLOYEE FIELDS TERMINATED BY "|" OPTIONALLY ENCLOSED BY '"' ESCAPE BY '\' -- 新增:指定反斜杠为转义字符,解析字段内的\" TRAILING NULLCOLS ( EMPID, EMPNAME_ADDRESS, -- 修正字段名:与CSV的列名EMPNAME_ADDRESS对应 SALARY "REPLACE(:SALARY, ',', '')", -- 可选:如果SALARY是数字类型,移除逗号转成纯数字 GRADE )
关键修改点说明
- 补全闭合引号:第三条记录必须以
"结束,让SQL*Loader明确识别字段边界,避免因找不到终止符报错; - ESCAPE BY配置:通过
ESCAPE BY '\'告诉SQL*Loader,字段内的\是转义字符,\"会被解析为字段内容里的单个双引号; - 字段名匹配:原控制文件里的
EMPNAME和CSV的EMPNAME_ADDRESS不对应,必须修正否则会导致字段映射错误; - 薪资字段处理:如果EMPLOYEE表的SALARY是数字类型,用
REPLACE(:SALARY, ',', '')去掉薪资里的千位分隔符,确保能正常插入数字。
无法修改源文件的备选方案
如果因业务限制不能修改CSV源文件,可以尝试使用FILLER字段结合正则截取来解析,但这种方式通用性较差,示例如下:
LOAD DATA INSERT INTO TABLE EMPLOYEE FIELDS TERMINATED BY "|" TRAILING NULLCOLS ( EMPID, RAW_EMPNAME_ADDRESS FILLER, -- 先读取整段未解析的内容 EMPNAME_ADDRESS "REGEXP_SUBSTR(:RAW_EMPNAME_ADDRESS, '\"(.*)\"', 1, 1, NULL, 1)", -- 用正则提取引号内的内容 SALARY "REPLACE(:SALARY, ',', '')", GRADE )
这种方案依赖Oracle的REGEXP_SUBSTR函数,仅适用于字段内容被双引号包裹的场景,优先推荐前面的标准修改方案。
内容的提问来源于stack exchange,提问作者user1463065
相关产品推荐
相关产品推荐

