将文件中的整行加载到 BOUNDFILLER 中,然后将您需要的部分提取到列中。您必须告诉 sqlldr 该字段由回车符/换行符终止(假设是 Windows 操作系统),因此它将从文件中读取整行作为一个字段。这里文件中的整行作为 BOUNDFILLER 被读入“dummy”。 “dummy”与列名不匹配,无论如何它都被定义为 BOUNDFILLER,所以整行都被“记住”了。控制文件中的下一行以与列名匹配的列开始,因此 sqlldr 尝试执行表达式。它从保存的“dummy”中提取一个子字符串并将其放入“col_a”列中。
简而言之,正则表达式返回字符串的后面但不包括第一个管道的部分,以及之前但不包括最后一个管道的部分。注意双反斜杠。无论如何,在我的环境中,当使用反斜杠来消除管道的特殊含义时(在方括号之间不需要)它在从 sqlldr 传递到正则表达式引擎时被剥离,因此控制文件中需要两个反斜杠
(通常管道符号是逻辑或)所以最后通过。如果您在这里遇到问题,请尝试一个反斜杠,看看会发生什么。猜猜我花了多长时间才弄清楚!
load data
infile 'x_test.dat'
TRUNCATE
into table x_test
FIELDS TERMINATED BY x'0D0A'
(
dummy BOUNDFILLER,
col_a expression "regexp_substr(:dummy, '[^|]*\\|(.+)\\|.*', 1, 1, NULL, 1)"
)
编辑:使用它来测试正则表达式。例如,如果末尾有一个额外的管道:
select regexp_substr('1|2|3|4|5|6|7|8|9|10|', '[^|]*\|(.+)\|.*\|', 1, 1, NULL, 1)
from dual;
第二次编辑:对于那些不习惯正则表达式的人,这个方法使用嵌套的 SUBSTR 和 INSTR 函数:
SQL> with tbl(str) as (
select '1|2|3|4|5|6|7|8|9|10|' from dual
)
select substr(str, instr(str, '|')+1, (instr(str, '|', -1, 2)-1 - instr(str
, '|')) ) after
from tbl;
AFTER
---------------
2|3|4|5|6|7|8|9
决定哪个更容易维护由您决定。想想你之后的开发者,无论如何都要发表评论! :-)