如何用Oracle SQLcl load加载含任意VARCHAR2值的CSV文件?
SQLcl 24.2加载含换行符CSV的问题与解决方案
问题场景
目标表结构
create table foo ( id number not null primary key, text varchar2(100) null );
待加载CSV文件内容
"ID","TEXT" 1,"Line1. Line2."
默认加载报错
使用默认命令 load foo FOO_DATA_TABLE.csv 加载时,SQLcl会误将字段内的换行识别为行终止符,导致解析失败:
Load data into table RC_OPS_USER.FOO csv column_names on delimiter , enclosures "" double encoding UTF8 row_limit off row_terminator default skip_rows 0 skip_after_names #ERROR Insert failed for row 1 #ERROR --Line contains invalid enclosed character data or delimiter at position 9 #ERROR Row 1 data follows: 1,"Line1. #ERROR Insert failed for row 2 #ERROR --Line contains invalid enclosed character data or delimiter at position 7 #ERROR Row 2 data follows: "Line2., #INFO Number of rows processed: 2 #INFO Number of rows in error: 2 #INFO No rows committed WARNING: Processed with errors
现有方案的局限性
通过修改行终止符 set loadformat csv term || 能解决当前案例的问题,但如果字段内容中恰好包含 ||,问题会再次出现,无法适配任意字符串值的加载需求。
根本解决办法
方法1:正确配置SQLcl的LOAD格式参数
SQLcl的LOAD命令原生支持识别被双引号包裹的字段内的换行符,只需明确配置解析规则,无需自定义行终止符:
先设置全局加载格式:
set loadformat csv enclosures '"' double row_terminator default
再执行加载:
load foo FOO_DATA_TABLE.csv
或者直接在LOAD命令中指定参数:
load foo FOO_DATA_TABLE.csv format csv column_names on enclosures '"' double row_terminator default
该配置会让SQLcl正确识别:被双引号包裹的字段内的换行符属于字段内容,而非行终止符;同时启用双引号转义规则(字段内的双引号用两个双引号表示),适配更复杂的字符串场景。
方法2:使用SQL*Loader(sqlldr)替代
如果SQLcl的LOAD命令仍无法满足复杂场景需求,可以使用Oracle官方的SQL*Loader工具,通过控制文件精确配置解析规则:
- 创建控制文件
foo.ctl:
LOAD DATA INFILE 'FOO_DATA_TABLE.csv' INTO TABLE foo FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS ( id, text CHAR(100) )
- 执行加载命令:
sqlldr your_username/your_password@your_database control=foo.ctl
SQL*Loader对包含换行符、特殊字符的CSV解析支持更稳定,能适配绝大多数复杂字符串场景。
内容的提问来源于stack exchange,提问作者Alin Hanghiuc
相关产品推荐
相关产品推荐

