SQL*Loader对不同文件及格式的处理方法
通常对于逻辑比较复杂的系统可能存在这种情况,因为导出的数据来源于多个系统, 因此可能提供给DBA的也是多个数据文件。这种情况并不一定需要执行多次加载,只需要在控制文件中做适当配置即可。不过有一点非常重要,提供的数据文件中的数据存放格式必须完全相同。
创建演示表tb_manager表
--创建tb_manager表
SCOTT@seiang11g>create table tb_manager(mgrno number,mname varchar2(30),job
varchar2(300),remark varchar2(4000));
Table created.
有多个数据文件,分别如下:
--数据文件1
[oracle@wjq SQL*Loader]$ vim wjq_test8_1.dat
10,SMITH,SALES MANAGER
11,ALLEN.W,TECH MANAGER
16,BLAKE,HR MANAGER
18,WJQ,TEACHER MASTER
--数据文件2
[oracle@wjq SQL*Loader]$ vim wjq_test8_2.dat
12,WARD,SERVICE MANAGER
13,TURNER,SELLS DIRECTOR
15,JAMES,HR DIRECTOR
--数据文件3
[oracle@wjq SQL*Loader]$ vim wjq_test8_3.dat
17,MILLER,PRESIDENT
创建控制文件,制定多个INFILE参数即可,控制文件如下:
--控制文件
[oracle@wjq SQL*Loader]$ vim wjq_test8.ctl
LOAD DATA
INFILE '/u01/app/oracle/SQL*Loader/wjq_test8_1.dat'
INFILE '/u01/app/oracle/SQL*Loader/wjq_test8_2.dat'
INFILE '/u01/app/oracle/SQL*Loader/wjq_test8_3.dat'
TRUNCATE INTO TABLE tb_manager
FIELDS TERMINATED BY ","
(
MGRNO,MNAME,JOB
)
执行sqlldr命令,并查看结果
--执行sqlldr命令
[oracle@wjq SQL*Loader]$ sqlldr scott/tiger
control=/u01/app/oracle/SQL*Loader/wjq_test8.ctl
SQL*Loader: Release 11.2.0.4.0 - Production on Tue Oct 31 15:45:43 2017
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 4
Commit point reached - logical record count 7
Commit point reached - logical record count 8
--查看结果
SCOTT@seiang11g>select * from tb_manager;
MGRNO MNAME JOB REMARK
---------- -------------------- ------------------------------
------------------------------
10 SMITH SALES MANAGER
11 ALLEN.W TECH MANAGER
16 BLAKE HR MANAGER
18 WJQ TEACHER MASTER
12 WARD SERVICE MANAGER
13 TURNER SELLS DIRECTOR
15 JAMES HR DIRECTOR
17 MILLER PRESIDENT
控制文件提供了多种逻辑判断方式,只要能把逻辑清晰地描述出来,SQL*Loader就能 按照指定的逻辑执行加载。
数据文件如下:
--数据文件
[oracle@wjq SQL*Loader]$ cat wjq_test9.dat
BON SMITH CLEAK 3904
BON ALLEN SALER,M 2891
BON WARD
SALER,"S" 3128
BON KING
PRESIDENT 2523
MGR 10 SMITH SALES MANAGER
MGR 11 ALLEN.W TECH MANAGER
MGR 16 BLAKE HR MANAGER
TMP SMITH 7369 CLERK 1020 20
TMP ALLEN 7499 SALESMAN 1930 30
TMP WARD
7521 SALESMAN 1580 30
TMP JONES 7566 MANAGER 3195 20
需求是将MGR开头的记录导入到tb_manager表,以BON开头的记录导入到tb_loader表,其他记录存放到废弃文件中,创建控制文件如下:
--控制文件
[oracle@wjq SQL*Loader]$ cat wjq_test9.ctl
LOAD DATA
INFILE '/u01/app/oracle/SQL*Loader/wjq_test9.dat'
DISCARDFILE '/u01/app/oracle/SQL*Loader/wjq_test9.dsc'
TRUNCATE
INTO TABLE tb_loader
WHEN TAB='BON'
(
TAB FILLER POSITION(1:3),
ENAME POSITION(6:10),
JOB POSITION(*+1:20),
SAL POSITION(*+3:27)
)
INTO TABLE tb_manager
WHEN TAB='MGR'
(
TAB FILLER POSITION(1:3),
MGRNO POSITION(6:7),
MNAME POSITION(9:15),
JOB POSITION(*+2:30)
)
虽然这个控制文件看起来比之前的都要复杂,但只有一个新语法,即关键字,我们这里通过WHEN来实现判断,很容易理解。同时,指定了DISCARDFILE参数,以生成不满足加载条件的废弃文件,如果你有心,不妨等执行完sqlldr命令后査看wjq_test9.dsc文件和wjq_test9.log文件。
另外注意,控制文件中WHEN逻辑判断不支持OR关键字,因此如果你的判断条件有多个,则只能通过AND连接,而不能直接使用OR。
执行sqlldr命令,并查看结果
--执行sqlldr命令
[oracle@wjq SQL*Loader]$ sqlldr scott/tiger
control=/u01/app/oracle/SQL*Loader/wjq_test9.ctl
SQL*Loader: Release 11.2.0.4.0 - Production on Tue Oct 31 15:55:48 2017
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 11
--查看结果
SCOTT@seiang11g>select * from tb_loader;
ENAME JOB SAL COMM
---------- ------------------------------ ---------- ----------
SMITH CLEAK 3904
ALLEN SALER,M 2891
WARD SALER,"S" 3128
KING PRESIDENT 2523
SCOTT@seiang11g>select * from tb_manager;
MGRNO MNAME JOB REMARK
---------- -------------------- ------------------------------
------------------------------
10 SMITH SALES MANAGER
11 ALLEN.W TECH MANAGER
16 BLAKE HR MANAGER
这里贴一下log日志和废弃日志
--log日志
[oracle@wjq SQL*Loader]$ cat wjq_test9.log
SQL*Loader: Release 11.2.0.4.0 - Production on Tue Oct 31 15:55:48 2017
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Control File:
/u01/app/oracle/SQL*Loader/wjq_test9.ctl
Data File:
/u01/app/oracle/SQL*Loader/wjq_test9.dat
Bad File: /u01/app/oracle/SQL*Loader/wjq_test9.bad
Discard File:
/u01/app/oracle/SQL*Loader/wjq_test9.dsc
(Allow all discards)
Number to load: ALL
Number to skip: 0
Errors allowed: 50
Bind array: 64 rows, maximum of
256000 bytes
Continuation: none specified
Path used: Conventional
Table TB_LOADER, loaded when TAB = 0X424f4e(character 'BON')
Insert option in effect for this table: TRUNCATE
Column Name Position Len
Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
TAB
1:3 3 CHARACTER
(FILLER FIELD)
ENAME
6:10 5 CHARACTER
JOB
NEXT+1:20 19 CHARACTER
SAL
NEXT+3:27 24 CHARACTER
Table TB_MANAGER, loaded when TAB = 0X4d4752(character 'MGR')
Insert option in effect for this table: TRUNCATE
Column Name Position Len
Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
TAB
1:3 3 CHARACTER
(FILLER FIELD)
MGRNO
6:7 2 CHARACTER
MNAME
9:15 7 CHARACTER
JOB
NEXT+2:30 28 CHARACTER
Record 8: Discarded - failed all WHEN clauses.
Record 9: Discarded - failed all WHEN clauses.
Record 10: Discarded - failed all WHEN clauses.
Record 11: Discarded - failed all WHEN clauses.
Table TB_LOADER:
4 Rows successfully loaded.
0 Rows not loaded due to data errors.
7 Rows not loaded because all WHEN
clauses were failed.
0 Rows not loaded because all fields
were null.
Table TB_MANAGER:
3 Rows successfully loaded.
0 Rows not loaded due to data errors.
8 Rows not loaded because all WHEN
clauses were failed.
0 Rows not loaded because all fields
were null.
Space allocated for bind array: 7168 bytes(64 rows)
Read buffer bytes: 1048576
Total logical records skipped: 0
Total logical records read: 11
Total logical records rejected: 0
Total logical records discarded: 4
Run began on Tue Oct 31 15:55:48 2017
Run ended on Tue Oct 31 15:55:48 2017
Elapsed time was: 00:00:00.08
CPU time was: 00:00:00.02
--废弃日志
[oracle@wjq SQL*Loader]$ cat wjq_test9.dsc
TMP SMITH 7369 CLERK 1020 20
TMP ALLEN 7499 SALESMAN 1930 30
TMP WARD
7521 SALESMAN 1580 30
TMP JONES 7566 MANAGER 3195 20
假如某天你接到一项数据加载需求,用户提供了一份100万行的数据文件,告诉你只导后50万行,恭喜,你接到了一个正常的需求!
实现的方式较多,比如修改数据文件,只保留后50万行(Windows下借助EditPlus 这类文本工具可以轻松实现,Linux/UNIX下通过TAIL等命令也可以轻易实现),如果你人很懒,不想修改文件,那正合sqlldr胃口,人家早早地就提供好了SKIP参数专用于满足此类需求。
数据文件如下:
--数据文件
[oracle@wjq SQL*Loader]$ vim wjq_test10.dat
#This is data of emp
ENAME MGR JOB SAL
---------- ----- --------- ---------
SMITH 7902 CLERK 1020
LEN 7698 SALESMAN 1930
▽ARD
7698 SALESMAN 1580
JONES 7839 MANAGER 3195
MARTIN 7698 SALESMAN 1580
BLAKE 7839 MANAGER 3180
CLARK 7839 MANAGER 2172
SCOTT 7566 ANALYST 3220
KING PRESIDENT 4722
TURNER 7698 SALESMAN 1830
ADAMS 7788 CLERK 1320
JAMES 7698 CLERK 1280
FORD 7566 ANALYST 3220
MILLER 7782 CLERK 1022
我们只对该数据文件只从第4行开始导入,即前3行不进行导入,创建控制文件如下:
--控制文件
[oracle@wjq SQL*Loader]$ vim wjq_test10.ctl
LOAD DATA
INFILE '/u01/app/oracle/SQL*Loader/wjq_test10.dat'
TRUNCATE INTO TABLE tb_loader
(
ENAME position(1:6),
XCOL FILLER position(13:16),
JOB position(18:26),
SAL position(32:35)
)
执行sqlldr命令,并查看结果
--执行sqlldr命令
[oracle@wjq SQL*Loader]$ sqlldr scott/tiger
control=/u01/app/oracle/SQL*Loader/wjq_test10.ctl skip=3
SQL*Loader: Release 11.2.0.4.0 - Production on Tue Oct 31 16:12:11 2017
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 14
--查看结果
SCOTT@seiang11g>select * from tb_loader;
ENAME JOB SAL COMM
---------- ------------------------------ ---------- ----------
SMITH CLERK 1020
ALLEN SALESMAN 1930
WARD SALESMAN 1580
JONES MANAGER 3195
MARTIN SALESMAN 1580
BLAKE MANAGER 3180
CLARK MANAGER 2172
SCOTT ANALYST 3220
KING PRESIDENT 4722
TURNER SALESMAN 1830
ADAMS CLERK 1320
JAMES CLERK 1280
FORD ANALYST 3220
MILLER CLERK 1022
如果用户要求较高,明确指定只加载第XX到第XX行的记录,sqlldr还有一个参数叫LOAD,配置LOAD参数即可轻松实现。
这里仍使用上述数据文件,需求改为只导入第4到9行的记录,我们连控制文件都不需要修改,只需要在执行sqlldr时再加上LOAD参数即可:
执行sqlldr命令(即skip=3跳过前3行,load=6,加载接下来的6行记录),并查看结果
--执行sqlldr命令
[oracle@wjq SQL*Loader]$ sqlldr scott/tiger
control=/u01/app/oracle/SQL*Loader/wjq_test10.ctl skip=3 load=6
SQL*Loader: Release 11.2.0.4.0 - Production on Tue Oct 31 16:15:13 2017
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 6
--查看结果
SCOTT@seiang11g>select * from tb_loader;
ENAME JOB SAL
COMM
---------- ------------------------------ ---------- ----------
SMITH CLERK 1020
ALLEN SALESMAN 1930
WARD SALESMAN 1580
JONES MANAGER 3195
MARTIN SALESMAN 1580
BLAKE MANAGER 3180
由于标准换行符也是sqlldr识别数据行结束的标志符,因此要将含换行符的数据加载到表中稍复杂一点点,而且需要根据实际情况来处理,不同情况的处理方式也不一样,
但基本思路是相同的,就是要同sqlldr指明什么时候才需要进行换行操作。
在手工指定换行符的情况下,数据文件中的换行符并不是标准的换行标志,而是用户自定义的一个标识字符(或多个字符组成),这种情况的处理比较简单,如数据文件如下:
--数据文件
[oracle@wjq SQL*Loader]$ vim wjq_test11_1.dat
10,SMITH,SALES MANAGER,This is SMITH.\nHe is a Sales Manager.
11,ALLEN.W,TECH MANAGER,This is ALLEN.W.\nHe is a Tech Manager.
16,BLAKE,HR MANAGER,This is BLAKE.\nHe is a Hr Manager.
我们可以通过控制文件,在数据加载前处理remark列的数据,将用户指定的字符替换为chr(10),即标准换行符,创建控制文件如下:
--控制文件
[oracle@wjq SQL*Loader]$ vim wjq_test11_1.ctl
LOAD DATA
INFILE '/u01/app/oracle/SQL*Loader/wjq_test11_1.dat'
TRUNCATE INTO TABLE tb_manager
FIELDS TERMINATED BY ","
(
MGRNO,
MNAME,
JOB,
REMARK
"REPLACE(:remark,'\\n',chr(10))"
)
这里需要注意的是,替换时必须指定"\\n"而不只是"\n",因为"\n"会被SQLLDR 识别成换行符并转换成换行标志,这样可能导致数据加载出错。而是默认转义符,指定该转义符后sqlldr就会将"\n"识别成普通字符了。
执行sqlldr命令,并查看结果
--执行sqlldr命令
[oracle@wjq SQL*Loader]$ sqlldr scott/tiger
control=/u01/app/oracle/SQL*Loader/wjq_test11_1.ctl
SQL*Loader: Release 11.2.0.4.0 - Production on Tue Oct 31 16:21:04 2017
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 3
--查看结果
SCOTT@seiang11g>select * from tb_manager;
MGRNO MNAME JOB REMARK
---------- -------------------- ------------------------------
------------------------------
10 SMITH SALES MANAGER This is SMITH.
He is a Sales Manager.
11 ALLEN.W TECH MANAGER This is ALLEN.W.
He is a Tech Manager.
16 BLAKE HR MANAGER This is BLAKE.
He is a Hr Manager.
数据文件如下:
--数据文件
[oracle@wjq SQL*Loader]$ cat wjq_test11_2.dat
10 SMITH SALES MANAGER THIS IS
SMITH.
HE IS A SALES MANAGER.
11 ALLEN.W TECH MANAGER THIS IS ALLEN.W
HE IS A TECH MANAGER.
16 BLAKE HR MANAGER THIS IS BLAKE.
HE IS A HR MANAGE.
(特别注意:因为使用的FIX固定长度,所以一定要注意每一行数据的长度,不够的使用空格来代替,否则在加载的使用会报错,报错信息如下所示:
SQL*Loader-501: Unable to read file (wjq_test11_2.dat)
SQL*Loader-566: partial record found at end of datafile
SQL*Loader-2026: the load was aborted because SQL Loader cannot continue.
报错的原因并不是说读不到要加载的数据文件,相反,虽然出现了报错的信息,也有可能部分数据已经导入进去了,报错因为你的存在数据并不是你所FIX的长度,所以出现报错,故在使用FIX的时候一定要注意这一点)
创建控制文件如下:
--控制文件
[oracle@wjq SQL*Loader]$ vim wjq_test11_2.ctl
LOAD DATA
INFILE '/u01/app/oracle/SQL*Loader/wjq_test11_2.dat' "FIX 65"
TRUNCATE INTO TABLE tb_manager
(
MGRNO POSITION(1:2),
MNAME POSITION(*+1:10),
JOB POSITION(*+1:24),
REMARK POSITION(*+1:63)
)
FIX是INFILE关键字的一个属性,INFILE不仅有FIX属性,还有VAR和STR等属性
执行sqlldr命令,并查看结果
--执行sqlldr命令
[oracle@wjq SQL*Loader]$ sqlldr scott/tiger
control=/u01/app/oracle/SQL*Loader/wjq_test11_2.ctl
SQL*Loader: Release 11.2.0.4.0 - Production on Wed Nov 1 10:37:45 2017
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 3
--查看结果
SCOTT@seiang11g>select * from tb_manager;
MGRNO MNAME JOB REMARK
---------- -------------------- ------------------------------
----------------------------------------
10 SMITH SALES MANAGER THIS IS SMITH.
HE IS A SALES MANAGER.
11 ALLEN.W TECH
MANAGER THIS IS
ALLEN.W.
HE IS A TECH MANAGER.
16 BLAKE HR MANAGER THIS IS BLAKE.
HE
IS A HR MANAGER.
这种方式其实就是在加载数据文件之前,先通过FIX属性指定每行的长度(这里每行65个字符,包括换行符在内,该例子上不够字符的用空格来代替了,注意上面数据文件中的结尾的空格),到了指定长度就换行,不管中间有没有换行符,因此仅能用于定长字符串的数据文件,因为只有字符串定长,你才知道应该在INFILE处指定什么值。
针对上述的数据文件也可以通过使用CONCATENATE属性处理换行符来处理换行符,控制文件内容如下所示:
[oracle@wjq SQL*Loader]$ vim wjq_test11_2.ctl
LOAD DATA
INFILE '/u01/app/oracle/SQL*Loader/wjq_test11_2.dat'
CONCATENATE 2 INTO TABLE tb_manager
(
MGRNO POSITION(1:2),
MNAME POSITION(*+1:10),
JOB POSITION(*+1:24),
REMARK POSITION(*+1:63)
"REPLACE(upper(:REMARK),'HE',chr(10)||'HE')"
)
前面提到INFILE关键字还支持VAR属性,语法格式为INFILE filename "var
n", n的值不能超过40,否则会报错,如果不指定n则默认值为5。
本小节就演示通过这种方式处理换行符。总的来说,这确实是相当有才的一种方式, 首先通过VAR属性在每行开头指定一个固定长度的字符串,该字符串指明该行的长度,通过这种方式支持变长字符串。
数据文件如下:
--数据文件
[oracle@wjq SQL*Loader]$ vim wjq_test11_3.dat
06110,SMITH,SALES MANAGER,This is SMITH.
He is a Sales Manager.
06311,ALLEN.W,TECH MANAGER,This is ALLEN.W.
He is a Tech Manager.
05516,BLAKE,HR MANAGER,This is BLAKE.
He is a Hr Manager.
数据文件中每行开头的061,063,055分别表示该行取61,63,55个字符
创建控制文件如下:
--控制文件
[oracle@wjq SQL*Loader]$ vim wjq_test11_3.ctl
LOAD DATA
INFILE '/u01/app/oracle/SQL*Loader/wjq_test11_3.dat' "var 3"
TRUNCATE INTO TABLE tb_manager
FIELDS TERMINATED BY ","
(MGRNO,MNAME,JOB,REMARK)
执行sqlldr命令,并查看结果
--执行sqlldr命令
[oracle@wjq SQL*Loader]$ sqlldr scott/tiger
control=/u01/app/oracle/SQL*Loader/wjq_test11_3.ctl
SQL*Loader: Release 11.2.0.4.0 - Production on Wed Nov 1 09:51:12 2017
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 3
--查看结果
SCOTT@seiang11g>select * from tb_manager;
MGRNO MNAME JOB REMARK
---------- -------------------- ------------------------------
----------------------------------------
10 SMITH SALES MANAGER This is SMITH.
He
is a Sales Manager.
11 ALLEN.W TECH MANAGER This is ALLEN.W.
He is a Tech Manager.
16 BLAKE HR MANAGER This is BLAKE.
He is a Hr Manager.
①这种方式可以视为第2种方式的变种,该方法不在INFILE处指定行长度,而改为在每行的行首位置标注该行长度,以支持变长类型的数据格式。
②综合来看,这两种方式实用价值都比较低,先不说用户是否真有如此耐心来生成这样格式的数据文件,就算用户按照这种格式提供,要知道windows、Linux/UNIX下因操作系统自身原因,对换行符识别也不同,在Windows环境下换行标志由"回车chr(13)+换行chr(10)" 两个字节组成,而Linux/UNIX环境则是"换行chr(10)"一个字节,也就是说指定了长度,操作系统变了以后,长度有可能也得跟着变,这就造成用户提供的数据文件通用性较差。
③有没有一种更简单的方式呢?事实上确实没有太简单的方式,在前面的内容中就提到, 你需要为sqlldr指明什么时候应该换行,因此对数据文件进行预处理是必然的,不过相对来讲,下面将要介绍的方式更易于操作,也更可行一些。
这种方式也需要先对数据文件做处理,在记录换行处打上一个标记,比如"丨"(当然可以定义为其他字符,但注意不要与要导入的数据有冲突),这样sqlldr见到该字符就知道换行的时候到了。
由于单个字符出现在导入数据中的机率较高,因此建议换行标志尽可能由多个字符组成,通常习惯于定义“字符+换行符”作为新的换行标记,这里我们也采用这种方式。
数据文件和控制文件如下:
--数据文件
[oracle@wjq SQL*Loader]$ vim wjq_test11_4.dat
10,SMITH,SALES MANAGER,This is SMITH.
He is a Sales Manager.|
11,ALLEN.W,TECH MANAGER,This is ALLEN.W.
He is a Tech Manager.|
16,BLAKE,HR MANAGER,This is BLAKE.
He is a Hr Manager.|
--控制文件
[oracle@wjq SQL*Loader]$ vim wjq_test11_4.ctl
LOAD DATA
INFILE '/u01/app/oracle/SQL*Loader/wjq_test11_4.dat' "str '|\n'"
TRUNCATE INTO TABLE tb_manager
FIELDS TERMINATED BY ","
(MGRNO,MNAME,JOB,REMARK)
执行sqlldr命令,并查看结果
--执行sqlldr命令
[oracle@wjq SQL*Loader]$ sqlldr scott/tiger
control=/u01/app/oracle/SQL*Loader/wjq_test11_4.ctl
SQL*Loader: Release 11.2.0.4.0 - Production on Wed Nov 1 09:45:28 2017
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 3
--查看结果
SCOTT@seiang11g>select * from tb_manager;
MGRNO MNAME JOB REMARK
---------- -------------------- ------------------------------ ----------------------------------------
10 SMITH SALES MANAGER This is SMITH.
He is a Sales Manager.
11 ALLEN.W TECH MANAGER This is ALLEN.W.
He is a Tech Manager.
16 BLAKE HR MANAGER This is BLAKE.
He is a Hr Manager.
STR属性中支持两种字符指定方式:
'char_string':普通字符,即标准的可见字符,不过也有些不可见字符可以通过下列反斜杠标识的方式在字符串模式中指定:
\n:表示换行。
\t:表示行制表符(tab)。
\f:表示换页。
\v:表示列制表符。
\r:表示回车。
说到这里,又不得不再次提及Windows和Linux/UNIX对换行符识别的差异,Linux/UNIX下指定"\n"即可,Windows下需要指定"\r\n"才表示一个完整的换行符。
X'hex_string':二进制字符。对于一些不可见字符,如像回车换行这类字符,可以将其转换成十六进制,然后再通过str X'hex_str'方式指定。
比如上述控制文件中的功能如果用二进制字符表示,形式如下:
INFILE ldr_case11_4.dat "str X'7C0A'"
要査看指定字符的十六进制编码,可以通过UTL_RAW.CAST_TO_RAW生成,例如:
SCOTT@seiang11g>select utl_raw.cast_to_raw('|'||chr(10)) from dual;
UTL_RAW.CAST_TO_RAW('|'||CHR(10))
--------------------------------------------------------------------------------
7C0A
这种方式相当于自定义一个换行标志,标准换行符不再拥有特殊的意义,只是作为要加载数据的一部分。较第一种方式而言最大的优势是,数据文件相对更容易处理,只需要在生成数据文件时,最后一列附加一个指定字符即可,对于稍有SQL基础的人来说,这都是小case。
作者:SEian.G(苦练七十二变,笑对八十一难)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。