java调用sqlldr导入csv文件数据到临时表
package cn.com.file;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Client {
public static void main(String args[]) throws FileNotFoundException
{
String path = "E:\\PORT";
String templateFile = "1.ctl";
String fileLists = "index.txt";
String commandText = "sqlldr.exe userid=webrescmxj/res4cmxj@resdb control=e:/PORT/tmp.ctl log=e:/PORT/1.log";
// 1.获取模板SQL
BufferedReader tReader = new BufferedReader(new FileReader(path + "\\" + templateFile));
StringBuffer buffer = new StringBuffer(); //记录模板SQL
String str = null;
try {
while((str = tReader.readLine())!=null){
buffer.append(str);
}
} catch (IOException e) {
e.printStackTrace();
}
//System.out.println(buffer.toString()); /* 测试打印使用 */
//2.拼装导入SQL
BufferedReader lsReader = new BufferedReader(new FileReader(path + "\\" + fileLists));
String tmpSQL = null; //记录模板SQL
str = null; //初始化
try {
while ((str = lsReader.readLine())!=null) {
tmpSQL = buffer.toString().replace("DEFAULT", path + "\\" + str);
System.out.println(tmpSQL);
//3. 将拼装好的SQL写入临时文件
File f = new File(path + "\\" + "tmp.ctl");
BufferedWriter writer = new BufferedWriter(new FileWriter(f));
writer.write(tmpSQL);
writer.flush();
writer.close(); //关闭写出
Process proc = Runtime.getRuntime().exec(commandText); // 执行SQLLDR操作
//proc.waitFor();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
CTL文件内容:
load data infile 'PORT-20140307203455.csv'
append into table TRANS_PORT
(
CUID char terminated by ',' OPTIONALLY ENCLOSED BY '"',
LABEL_CN char terminated by ',' OPTIONALLY ENCLOSED BY '"',
RELATED_CARD char terminated by ',' OPTIONALLY ENCLOSED BY '"',
CARD_CUID char terminated by ',' OPTIONALLY ENCLOSED BY '"',
NE_NAME char terminated by ',' OPTIONALLY ENCLOSED BY '"',
RELATED_NE_CUID char terminated by ',' OPTIONALLY ENCLOSED BY '"',
EMS_NAME char terminated by ',' OPTIONALLY ENCLOSED BY '"',
RELATED_EMS_CUID char terminated by ',' OPTIONALLY ENCLOSED BY '"',
RATE char terminated by ',' OPTIONALLY ENCLOSED BY '"',
PORT_STATE char terminated by ',' OPTIONALLY ENCLOSED BY '"',
PORT_NO char terminated by ',' OPTIONALLY ENCLOSED BY '"',
PORT_TYPE char terminated by ',' OPTIONALLY ENCLOSED BY '"',
DOMAIN char terminated by ',' OPTIONALLY ENCLOSED BY '"',
MSTP_PORT_TYPE char terminated by ',' OPTIONALLY ENCLOSED BY '"',
CURRENTWAVENUM char terminated by ',' OPTIONALLY ENCLOSED BY '"',
WAVE_RATE char terminated by whitespace OPTIONALLY ENCLOSED BY '"')
22222222222222222222222222222222222222222222222222222222222222
命令语句 "sqlldr user/pwd@sid control=a.ctl log=log.txt bad = bad.txt"
在windows的CMD命令行和UNIX里面直接调用没有任何问题。速度很快,可以上传成功。
但是我用java的Runtime.getRuntime().exec("sqlldr user/pwd@sid control=a.ctl log=log.txt bad = bad.txt"); 来调用sqlldr, 如果数据量小,没有任何问题,可以上传数据成功,但是数据大于2M的时候就会上传到一半突然停下来。LOG文件一直是空的,数据库也能看到上传了一部分数据,但是并没有上传成功。
感觉上是JAVA的Runtime.getRuntime().exec();被打断了。但是又没有什么办法测试。在windows里面用JAVA调也没问题,只有在UNIX里面出问题。。请教各位吧。有没有遇到过这种问题的帮忙一下。
问题补充:
那能不能说一下具体的解决方案呢?
我的平台是IBM AIX 400, jdk1.6,oracle 10g
---------------------解决方案:
正好解决了我心中的疑问,非常感谢!
我们的程序一开始就是exec完了接着waitFor(),但bat文件执行不完整:
Process proc = Runtime.getRuntime().exec(cmd);
proc.waitFor();
后面的build中在waitFor()之前读取了数据流,bat文件就可以完整执行了:
Process proc = Runtime.getRuntime().exec(cmd);
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "Error");
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "Output");
errorGobbler.start();
outputGobbler.start();
proc.waitFor();
class StreamGobbler extends Thread {
InputStream is;
String type;
StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
if (type.equals("Error"))
LogManager.logError(line);
else
LogManager.logDebug(line);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
TestPrint.bat:
echo P1=%1 >D:\2.1.2env\2.1.2home\CompuSet\output\TestPrint.log
echo P2=%2 >>D:\2.1.2env\2.1.2home\CompuSet\output\TestPrint.log
echo P3=%3 >>D:\2.1.2env\2.1.2home\CompuSet\output\TestPrint.log
echo P4=%4 >>D:\2.1.2env\2.1.2home\CompuSet\output\TestPrint.log
echo P5=%5 >>D:\2.1.2env\2.1.2home\CompuSet\output\TestPrint.log
echo P6=%6 >>D:\2.1.2env\2.1.2home\CompuSet\output\TestPrint.log
Bad_TestPrint.log:
P1=C:\xPression\CompuSet\output\MartyTestOut1.afp
P2=Literal1
P3="Rick Skinner"
P4=Parameter3
Good_TestPrint.log
P1=C:\xPression\CompuSet\output\MartyTestOut1.afp
P2=Literal1
P3="Rick Skinner"
P4=Parameter3
P5=Parameter4
P6=Parameter5
-----------------------------sqlldr
sqlldr是cmd下的命令,用来将文本格式数据导入到数据库中。
命令格式:
sqlldr username/password@sid control=*.ctl
*.ctl格式为:
load
infile "d://test.txt" 外部数据文件
infile "d://test1.txt" 可指定多个数据文件
append into table test 向表中追加数据
fields terminated by "," 外部文件的数据以“,”分隔
trailing nullcols 表中的字段没有对应的值时填充空值
(
id integer external, integer external 表示插入的数据是string,如果只保留integer,表示插入的数据是二进制
name "upper(:name)", 将插入的值转换为大写
con ":id||:name", 表中CON列的值是ID和NAME的组合值
dt date"yyyy-mm-dd" 插入日期型数据
)
在append的位置还可以用以下列表中的一个值:
insert 向表中插入值,但要求表开始时为空
replace delete表中的数据,然后插入新值
append 向表中追加数据
truncate trunctate表,然后插入新值
例:
C:\Users\wzj>sqlldr scott/tiger control=d:/dept.ctl
dept.ctl的内容如下:
load
infile "d://test.txt"
append into table tt
fields terminated by ","
trailing nullcols
(
id integer external,
name "upper(:name)",
con ":id||:name",
dt date"yyyy-mm-dd"
)
test.txt的数据如下
1,a,,2007-07-8
2,b,,2008-07-8
3,c,,2009-07-8
SQL> desc tt ;
名称 是否为空? 类型
----------------------------------------------------- -------- -------------
--------------------
ID VARCHAR2(10)
NAME VARCHAR2(20)
CON VARCHAR2(30)
DT DATE
33333333333333333333333333333333333333333333333333333333333333333333
前提:安装了oracle客户端。
在“开始”->“运行”,输入“cmd”,回车。在打开的dos窗口里输入:sqlldr。看看是否安装了
下面,我为了快速学习,先忽略参数的说明。只管用一个简单的例子。
我在本机上安装了Linux的oracle数据库,现在先建立一个测试的表:
create table tdsxhwn.tbtestsqlldr(
id int,
name varchar(10)
)
然后配置一个连接服务,别名为LOCALHOST_ORCL
打开PL/SQL即可看
如果没有PL/SQL,也可以在$ORACLE_HOME\client_1\NETWORK\ADMIN\tnsnames.ora文件找到:
LOCALHOST_ORCL = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.88)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = orcl) ) ) |
现在,我在“D:\sqlldr”文件夹里创建两个文件:
control.txt文件
data.txt
然后在刚才的dos窗口里输入:
sqlldr userid=tdsxhwn/td$123@LOCALHOST_ORCL control=d:\sqlldr\control.txt log= d:\sqlldr\out.log
上面sqlldr的格式是:
sqlldr userid=用户/密码@服务别名 control= control文件路径 log=日志文件路径
通过例子来学习
例1:用包含数据的文本导入.
1)、现在有一个要导入数据库的数据的文本1.txt,文件存放路径d:\1.txt,格式如下:
123,312u
124,dsfsd
5423,rtdf34
2)、在数据库中创建要导入的表test(数据库用户名/密码:test/test,默认在本机)
create table test
(num number(11),
var varchar2(12)
)
3)、编写ctl控制文件 test.ctl,文件存放路径:d:\test.ctl
load data
infile 'd:\1.txt'
append into table test
fields terminated by ','
(num,var)
4)、命令提示符下执行一下命令
sqlldr userid=jscs/jscs@jscs control=d:\test.ctl
注:
infile 'd:\1.txt' //需要装载的数据文件的路径,如果数据在本文件中,则用infile *
append into table test //数据载入的表:
(1)append 表示表中有数据,加在后面
(2)INSERT 表示装入空表,有数据则停止。默认值
(3)REPLACE 原先表中如果有数据,会被删除
(4)TRUNCATE 如果要载入的数据与现在的数据相同,载入的数据替换现存的数据。
fields terminated by ','
//数据用是','格开的,如上(1)处,用by X'09',即16进制的"09"代表TAB制表符,常用于excel转换的tab制表符文件的数据的导入
(num,var) //数据表中要载入的字段
例2:要导入的数据在ctl文件中
1)数据库表同上例1
2)编写ctl控制文件test2.ctl,文件存放路径:d:\test2.ctl
load data
CHARACTERSET 'UTF8'-----字符集设定,这样才能导入中文
infile *
append into table test
fields terminated by ','
trailing nullcols---------表示允许为空
(num,var,dat DATE "YYYY-MM-DD HH24:MI:SS)
begindata
123,312u,2011-12-11 11:11:11
124,dsfsd,2011-12-11
5423,rtdf34,2011-12-11 12:11:11
............
3)命令提示符下执行一下命令
sqlldr userid=jscs/jscs@jscs control=d:\test2.ctl
例3:创建如下字符串结构表
load data
infile DED20100730099.531
append into table ask_tem_ded
(recordtag position (01:02) char(2),
event_type position (03:12) char(10),
dedtype position (13:14) char(2),
serial position (15:34) char(20),
msisdn position (35:49) char(15),
spcode position (50:69) char(20),
opercode position (70:89) char(20),
chrgtype position (90:91) char(2),
lastdate position (92:105) char(14),
dedtime position (106:119) char(14),
dedfee position (120:125) char(6),
preserve position (126:145) char(20)
)
sqlldr userid=jscs/jscs@jscs control=d:\test2.ctl
―――――――――――――――――参数说明――――――――――――――――――
二、有效的关键字:
userid -- ORACLE username/password
control – 控制文件
log – 记录的日志文件
bad – 坏数据文件
data – 数据文件
discard – 丢弃的数据文件
discardmax – 允许丢弃数据的最大值 (全部默认)
skip -- Number of logical records to skip (默认0)
load -- Number of logical records to load (全部默认)
errors – 允许的错误记录数 (默认50)
rows -- Number of rows in conventional path bind array or between direct path data saves(每次提交的记录数,默认: 常规路径 64, 所有直接路径)
bindsize -- Size of conventional path bind array in bytes(默认256000)
每次提交记录的缓冲区的大小(字节为单位,默认256000)
silent --禁止输出信息 (header,feedback,errors,discards,partitions)
direct – 使用直通路径方式导入 (默认FALSE)
parfile -- parameter file: name of file that contains parameter specifications
parallel -- 并行导入 (默认FALSE)
file -- File to allocate extents from
skip_unusable_indexes -- disallow/allow unusable indexes or index partitions(默认FALSE)
skip_index_maintenance -- do not maintain indexes, mark affected indexes as unusable(默认FALSE)
readsize -- Size of Read buffer (默认1048576)
与bindsize成对使用,其中较小者会自动调整到较大者。sqlldr先计算单条记录长度,乘以rows,如小于bindsize,不会试图扩张rows以填充bindsize;如超出,则以bindsize为准。
external_table -- use external table for load; NOT_USED, GENERATE_ONLY, EXECUTE(默认NOT_USED)
columnarrayrows -- Number of rows for direct path column array(默认5000)
streamsize -- Size of direct path stream buffer in bytes(默认256000)
multithreading -- use multithreading in direct path
resumable -- enable or disable resumable for current session(默认FALSE)
resumable_name -- text string to help identify resumable statement
resumable_timeout -- wait time (in seconds) for RESUMABLE(默认7200)
date_cache -- size (in entries) of date conversion cache(默认1000)
注意:有两种方式可以指定命令行参数:通过位置或者通过关键字。
(1)通过位置指定命令行参数的例子:'sqlldr scott/tiger foo';
(2)通过关键字指定命令行参数的例子:'sqlldr control=foo userid=scott/tiger';
不能前面使用关键字指定后面通过位置指定的混合方式;
比如:'sqlldr scott/tiger control=foo logfile=log' 是允许的;
但'sqlldr scott/tiger control=foo log'不允许。
通过位置指定命令行参数的时候,必须将“位置”放在user/passwd之前。
为清楚起见最好所有命令行参数都用关键字指定。
三、控制文件:一个控制命令的脚本文件,通常以ctl结尾,内容如下:
LOAD DATA
INFILE 't.dat' //要导入的文件
// INFILE 'tt.date' //导入多个文件
// INFILE * //表示要导入的内容就在control文件里 下面的BEGINDATA后面就是导入的内容
INTO TABLE table_name // 指定装入的表
BADFILE 'c:\bad.txt' //可选,指定坏文件地址,缺省在当前目录下生成与原文件名一致的.bad文件
//************* 以下是4种装入表的方式
APPEND // 原先的表有数据 就加在后面
// INSERT //装载空表 如果原先的表有数据 sqlloader会停止 默认值
// REPLACE // 原先的表有数据 原先的数据会全部删除
// TRUNCATE // 指定的内容和replace的相同 会用truncate语句删除现存数据
//************* 指定分隔符
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
// TERMINATED BY WRITESPACE //以空白分割
用java运行sqlldr:
private void runSqlldr(String path, String logPath) {
// java运行sqlldr
try {
String s = "sqlldr userid=" + info.getGoalUser() + "/"
+ info.getGoalPassword() + "@" + info.getDbAlias()
+ " control=" + path + " log=" + logPath
+ " errors=1000000 rows=10000";
Process process = Runtime.getRuntime().exec(s);
doWaitFor(process);
//这里就该执行完了
process.destroy();
process = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private int doWaitFor(Process p) {
int exitValue = -1; // returned to caller when p is finished
InputStream in = null;
InputStream err = null;
try {
in = p.getInputStream();
err = p.getErrorStream();
boolean finished = false; // Set to true when p is finished
while (!finished) {
try {
while (in.available() > 0) {
// Print the output of our system call
in.read();
}
while (err.available() > 0) {
// Print the output of our system call
err.read();
}
exitValue = p.exitValue();
finished = true;
} catch (IllegalThreadStateException e) {
}
}
} catch (Exception e) {
// unexpected exception! print it out for debugging...
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (err != null) {
try {
err.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// return completion status to caller
return exitValue;
}
44444444444444444444444444444444444444444444444444444444444444444444444
1.创建数据文件:
?如,在D:\创建 zhaozhenlong.txt 文件,文件内容为:
11,12,13
21,22,23
31,32,33
2、创建控制文件:
如,在D:\创建 zhaozhenlong.ctl 文件,文件内容为:
load da ta
infile 'd:\zhaozhenlong.txt'
append into table zhaozhenlong
fields terminated by ','
(c1,c2,c3)
3、在数据库中创建表:
create table zhaozhenlong(c1 varchar(20),c2 varchar(20),c3 varchar2(20));
4、在‘开始’/‘运行’中,执行:
sqlldr userid=cs/cs@orademo control=d:\zhaozhenlong.ctl
5、查询数据库:
select * from zhaozhenlong
结果为:
?C1 C2 C3
1 11 12 13
2 21 22 23
3 31 32 33
?
例2:
?
?关于 oracle 中 sqlldr 的用法
2005-12-30 21:13:49
大 中 小
这几天研究了一下 sqlldr 的用法,今天在这里写出来供有需要的同行享用.
现在有一个文件 Output.txt 内容如下:
?
Ivy,Lam,PR02004,2005,09,21,17,32,00,I,D,Main Door,PR,
Carmen,Siu,AC04023,2005,09,21,17,32,01,I,D,Main Door,Account,
Xing,Lee,CM06021,2005,09,21,17,32,02,I,D,Main Door,Communications,
Barry,Yu,MK05006,2005,09,21,17,32,02,I,D,Main Door,Marketing,
Overtime,nil,OV0001,2005,09,21,17,32,07,I,D,Main Door,Product,
Sammy,Mow,SA02322,2005,09,21,17,32,09,I,D,Main Door,Sales,
Emily,Fu,CM06024,2005,09,21,17,32,10,I,D,Main Door,Communications,
Stella,Chow,PT02145,2005,09,21,17,32,11,I,D,Main Door,Product,
?
是有规律的数据,中间都是用","分开的,现在我要将此文件导入到 oracle 中:
?
第一步,当然是建表,上面有一行中有几个数据就建几个字段.
?
二,写一个 *.ctl 的文件,内容如下
?
load da ta
infile 'D:\owen\work\CardAttendence\Completed\windows\Output.txt'
badfile 'D:\owen\work\CardAttendence\Completed\windows\Output.bad'
append
into table system.card_time_original
fields terminated by ","
(lName,fName,emp_id,year,month,day,hour,minute,second,inOut,status,doorName,dept)
三,在 doc 窗口下输入如下命令
?
sqlldr userid=system/111111@XE control=D:\owen\work\CardAttendence\Completed\windows\imp ortOne.ctl log=D:\owen\work\CardAttendence\Completed\windows\imp ort.log
?
注意:这里一定要是当前用户对此表有所有权限, 还有一定不能用 sys 用户,要不然会出错
?
如果要将此数据导入到两个表中(结构相同),那么可以把控制文件改为如下所示:
?
load da ta
infile 'D:\owen\work\CardAttendence\Completed\windows\Output.txt'
badfile 'D:\owen\work\CardAttendence\Completed\windows\Output.bad'
append
into table system.card_time_original
WHEN lName != ' '
fields terminated by ","
(lName POSITION(1),fName,emp_id,year,month,day,hour,minute,second,inOut,status,doorName,dept)
into table system.card_time_original_bak
WHEN lName != ' '
fields terminated by ","
(lName POSITION(1),fName,emp_id,year,month,day,hour,minute,second,inOut,status,doorName,dept)
?
FAQ_SQLLDR用法总结
在数据仓库项目实施过程中,ETL是重要的一环,实施的好与坏,关系到项目的成功与否。
在数据抽取领域,相应的工具有IBM DataStage,Informatica PowerCenter,这里介绍Oracle自带的SQLLODER,
这是在Oracle数据仓库实施过程中最容易掌握的工具。在介绍之前,先考虑下面问题:
?一、注意SQLLDR要解决的问题,即实现ETL过程的问题
1、导入表的数据类型为日期类型
2、导入数据过程中的转换问题
3、导入数据过程中的过滤问题
4、导入数据过程中的截取问题
5、导入空列在转换时可能会遇到的问题
6、导入数据的分割符问题,如逗号,制表符,空白符都是常见的
用法:
二、控制文件:一个控制命令的脚本文件,通常以ctl结尾,Test.ctl内容如下:
?
LOAD DA TA
INFILE 'F:\SQLLDR\da ta.txt'
INFILE 'F:\SQLLDR\da ta2.txt' //可以从多个文件导入数据
// INFILE * //导入的内容在本文件最后的BEGINDATA后面就是导入的内容
INTO TABLE sdata.T_TEST
?
//四种装载方式,四选一
APPEND // 原先的表有数据 就加在后面
// INSERT //装载空表 如果原先的表有数据 sqlloader会停止 默认值
// REPLACE // 原先的表有数据 原先的数据会全部删除
// TRUNCATE // 指定的内容和replace的相同 会用truncate语句删除现存数据
?
//过滤装载的数据
WHEN T_DATE = '2007-07-02' //大于和小于等其它比较还没解决
?
//指定分割符
FIELDS TERMINATED BY ',' // x'09' (制表符)
-- FIELDS TERMINATED BY WHITESPACE //以空白分割,实际这样分割危险
OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS // 表的字段没有对应的值时允许为空 ,这句很有用,默认加的好
?
//表的字段,可以在里面大做文章
(
T_ID FILLER, // FILLER 关键字 此列的数值不会被装载
T_DATE "CASE WHEN :T_DATE is null THEN TO_DATE('2999-12-31','yyyy-mm-dd') ELSE TO_DATE(:T_DATE,'yyyy-mm-dd') END",
?//日期类型特别说明,并且要指定其格式
//更一般的格式是T_DATE date ‘yyyy-mm-dd’
T_NAME POSITION(3:6) "UPPER(:T_NAME)", //用位置POSITION来告诉装载的数据
//"UPPER(:T_NAME)" 转换为大写,注意冒号
T_SEX position(*:8) , // 这个字段的开始位置在前一字段的结束位置
ENTIRE_LINE "UPPER(:T_NAME||:T_SEX)" //连接并转换为大写
)
?
/****可继续 插入数据到其他表
INTO TABLE sdata.T_TEST
INSERT
WHEN T_DATE = '2007-07-02' ? //大于和小于等其它比较还没解决
.//BEGINDATA // 与前面的INFILE?*对应,一般不会这样用吧?
//1,ajsdlkfjsdkl,0?
?
三、运行方法
命令窗口执行:
sqlldr userid=sdata/sdata@rasdevdb control=F:\SQLLDR\Test.ctl?
为了方便,一般写个bat 文件,在bat文件中输入上述的内容即可,最后在命令窗口中运行这个bat文件,原理是一样的。
总之,这其实是Oracle中的一个用法而已。
三、
对不规则数据源的处理
?
--TRAILING NULLCOLS // 表的字段没有对应的值时允许为空,这句很有用
例如:
对于由EXCEL文件导出成CSV文件时,有的行末没有数据会缺少分割符,这在DS中会报错的,在SQLLD
555555555555555555555555555555555555555555
导入sqlloader数据例子(when条件的,只能使用and连接,插入的顺序要跟文件中的列的顺序相同):
1,
options(skip=1)
load data
characterset UTF8
infile 'd:\xxkCommon\20120310_hb_cust_basic_data_month.csv'
replace
INTO TABLE T_CUSTOMER_ALL_TEMP
when CUSTOMER_TYPE != '政企' and CUSTOMER_TYPE!='公务政企' and CUSTOMER_TYPE!='公用'
FIELDS terminated by ',' OPTIONALLY ENCLOSED BY '"' --,分隔符
TRAILING NULLCOLS ( DT_DATE date 'yyyy-MM-dd',
CUST_ID,
phone1,
CUSTOMER_NAME,
ADDRESS,
ACNT_ADDR_FULL_TXT,
INCOME,
PROD_INST_TYPE)
2,(使用序列,序列放在最后一列进行自动添加)
options(skip=1)
load data
characterset UTF8
infile 'd:\xxkCommon\daily_subtotal_2012-03-27.txt'
append
INTO TABLE t_traffic_detail
fields terminated by X'09' --一个tab,分隔符
TRAILING NULLCOLS (
CALL_TIME date 'yyyy-MM-dd',
WAS_CALL_NUMBER,
CALL_NUMBER,
CALL_COUNT,
TRAFFIC_DETAIL_ID "SEQ_TRAFFIC_DETAIL.NEXTVAL"
)
使用该命令行,首先确保服务器安装oracle客户端,并且保证环境变量配置正确,例如:
path:D:\oracle\product\10.2.0\db_1\bin;%JAVA_HOME%/bin;%JAVA_HOME%/jre/bin;
同时在cmd中测试sqlldr,时候能够使用,如果能够使用则使用该命令:
sqlldr userid=user1/user1@database1 control='d:\input.ctl' log='d:\inputLog.log'
使用该命令则可以进行客户端导入,同时可观察日子文件中的信息,根据日志信息进行修改更正。
B:在Java定时任务中调用该方法
protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
String fileName="";
try {
fileName = ftpUtils.downFileCSV(ConstantConfig.COMMONFILEPATH, "_hb_cust_basic_data_month.csv", DateTime.getSssq());
if (fileName!=null&&!fileName.equals("")) {
//文件名称加上地址
fileName=ConstantConfig.COMMONFILEPATH+fileName;
//得到下载到本机的地址
File file = new File(fileName);
if (file.exists()) {
long start = System.currentTimeMillis();
String sqlCtlStr = "options(skip=1) \r\n" +
"load data \r\n" +
"characterset UTF8 \r\n"+
"infile '"+fileName+"'"+"\r\n"+
"replace \r\n"+
"INTO TABLE T_CUSTOMER_ALL_TEMP \r\n" +
"when CUSTOMER_TYPE != '政企' and CUSTOMER_TYPE!='公务政企' and CUSTOMER_TYPE!='公用'"+"\r\n"+
"FIELDS terminated by ',' OPTIONALLY ENCLOSED BY '\"' \r\n"+
"TRAILING NULLCOLS "+
"( " +
"DT_DATE date 'yyyy-MM-dd',"+"\r\n"+
"CUST_ID,"+"\r\n"+
"phone1,"+"\r\n"+
"CUSTOMER_NAME,"+"\r\n"+
"ADDRESS,"+"\r\n"+
"ACNT_ADDR_FULL_TXT,"+"\r\n"+
"POSTCODE,"+"\r\n"+
"DEV_BUREAU_NAME,"+"\r\n"+
"DEV_SUB_BUREAU_NAME,"+"\r\n"+
"CARD_TYPE,"+"\r\n"+
"CARD_CODE,"+"\r\n"+
"sex,"+"\r\n"+
"age,"+"\r\n"+
"CUSTOMER_TYPE,"+"\r\n"+
"TOTAL_DATA date 'yyyy-MM-dd',"+"\r\n"+
"PROD_INST_TYPE" +
")";
String fileCtl = ConstantConfig.COMMONFILEPATH+"customerMonthLoader.ctl";
String fileLog = ConstantConfig.COMMONFILEPATH+"customerMonthLog.log" ;
//写入文件
ConstantConfig.setCtlContent(fileCtl, sqlCtlStr);
String sqlLoaderCommand = "sqlldr " + ConstantConfig.SQLUSERID + " control=" + fileCtl + " log="+fileLog;
Process ldr= Runtime.getRuntime().exec(sqlLoaderCommand);
InputStream stderr = ldr.getInputStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ( (line = br.readLine()) != null){
System.out.println("*** " + line);
}
stderr.close();
isr.close();
br.close();
ldr.waitFor();
//删除下载到本地的文件
if (file.exists()) {
file.delete();
}
long end = System.currentTimeMillis();
long timeLoss = (end - start) / 1000;
logger.info("[1.月客户流量CTL脚本执行结束,已导入数据,生成日志文件" + fileLog + ",耗时" + timeLoss
+ "s!]");
//执行存储过程,比对数据进入到正式库中,并且添加流量信息
custAgrDAO.addCust("1");
long end2 = System.currentTimeMillis();
timeLoss = (end2 - end) / 1000;
logger.info("[1.周客户流量CTL脚本执行结束,已导入数据,生成日志文件" + fileLog + ",耗时" + timeLoss
+ "s!]");
}
}
} catch (IOException e) {
e.printStackTrace();
logger.error("导入月客户流量文件,名称为:"+fileName+"发生IO异常,异常原因为:"+e.getMessage());
} catch (InterruptedException e) {
e.printStackTrace();
logger.error("导入月客户流量文件,名称为:"+fileName+"发生IO异常,异常原因为:"+e.getMessage());
}
}
<pre name="code" class="html">public static void setCtlContent(String fileName,String sqlCtlStr){
File file = new File(fileName);
BufferedWriter writer;
try {
if (!file.exists()) {
file.createNewFile();
}
writer = new BufferedWriter(new FileWriter(file, false));
writer.append(sqlCtlStr);
writer.flush();
writer.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}</pre><br>
<p></p>
<pre></pre>
<br>
<br>
<p></p>
<p></p>
<p><br>
</p>
66666666666666666666666666666666666666666666666666666666666666