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。看看是否安装了

 

 

 

下面,我为了快速学习,先忽略参数的说明。只管用一个简单的例子。

 

我在本机上安装了Linuxoracle数据库,现在先建立一个测试的表:

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_USEDGENERATE_ONLYEXECUTE(默认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

 

转载于:https://www.cnblogs.com/qq3245792286/p/6180452.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java代码中调用执行shell脚本,sqlldr导数与使用sqlplus在shell调用执行存储过程。 linux环境中有2个dba的用户:oracle、erm 还有1个web用户:erm 在linux环境中,这三个用户都可以直接在任意目录下执行该shell脚本,可是在java代码中调用shell脚本时,报了如下4个错误: 1、sqlldr: command not found 2、sqlplus: command not found 3、0750: You may need to set ORACLE_HOME to your Oracle software directory 4、Message 2100 not found; No message file for product=RDBMS, facility=ULMessage 2100 not found; No message file for product=RDBMS, facility=UL$ 检查了dba用户和web用户下关于oracle的所有环境变量发现没有问题 (/home/oracle/.profile 与 /home/erm/.profile 环境变量文件为隐藏文件需使用 ls -a 命令查看) 在网上查了一遍以后有如下几种处理办法: 1、没有oracle_home目录的执行权限,无法进入到bin目录,使用chmod 755 $oracle_home更改目录权限;使用chmod 755 $oracle_home/lib更改目录权限;对目录$oracle_home/rdbms/mesg目录赋予相应权限;当需要给非oracle用户配置使用sqlldr时,不单需要配置环境变量,还需要把相关目录的访问权限赋予该用户。【采用此法测试以后还是出现上面的错误】 2、用sh直接执行shell和在java直接执行shell是有区别的,要在shell文件内增加oracle的环境变量即. /home/oracle/.bash_profile 这句话,否则在执行sqlldr会报如下异常: Message 2100 not found; No message file for product=RDBMS...... facility=UL 【采用此法测试以后继续报错,但是这个方法有引导作用,继续往下看】 因为我在linux环境下执行shell脚本时sqlldr命令和sqlplus命令是正常执行的,没有任何问题,但是在java代码中调用脚本时却报错,所有排除了其他原因,只可能是环境变量的问题, 于是我把oracle的所有环境变量直接复制到shell脚本文件中,在java调用了一下,然后所有问题迎刃而解! 具体代码参看文件内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值