• 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.2env2.1.2homeCompuSetoutputTestPrint.log
    echo P2=%2 >>D:2.1.2env2.1.2homeCompuSetoutputTestPrint.log
    echo P3=%3 >>D:2.1.2env2.1.2homeCompuSetoutputTestPrint.log
    echo P4=%4 >>D:2.1.2env2.1.2homeCompuSetoutputTestPrint.log
    echo P5=%5 >>D:2.1.2env2.1.2homeCompuSetoutputTestPrint.log
    echo P6=%6 >>D:2.1.2env2.1.2homeCompuSetoutputTestPrint.log

    Bad_TestPrint.log:

    P1=C:xPressionCompuSetoutputMartyTestOut1.afp  
    P2=Literal1 
    P3="Rick Skinner" 
    P4=Parameter3

    Good_TestPrint.log

    P1=C:xPressionCompuSetoutputMartyTestOut1.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:Userswzj>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_HOMEclient_1NETWORKADMIN nsnames.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:sqlldrcontrol.txt log= d:sqlldrout.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: est.ctl
    load data
    infile 'd:1.txt'
    append into table test
    fields terminated by ','
    (num,var)
    4)、命令提示符下执行一下命令
    sqlldr userid=jscs/jscs@jscs control=d: est.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: est2.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: est2.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: est2.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:ad.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:owenworkCardAttendenceCompletedwindowsOutput.txt'
    badfile 'D:owenworkCardAttendenceCompletedwindowsOutput.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:owenworkCardAttendenceCompletedwindowsimp ortOne.ctl log=D:owenworkCardAttendenceCompletedwindowsimp ort.log
    ?
    注意:这里一定要是当前用户对此表有所有权限, 还有一定不能用 sys 用户,要不然会出错
    ?
    如果要将此数据导入到两个表中(结构相同),那么可以把控制文件改为如下所示:
    ?
    load da ta
    infile 'D:owenworkCardAttendenceCompletedwindowsOutput.txt'
    badfile 'D:owenworkCardAttendenceCompletedwindowsOutput.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:SQLLDRda ta.txt'

    INFILE 'F:SQLLDRda 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:SQLLDRTest.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:xxkCommon20120310_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:xxkCommondaily_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:oracleproduct10.2.0db_1in;%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) " +
    "load data " +
    "characterset UTF8 "+
    "infile '"+fileName+"'"+" "+
    "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,"+" "+
    "POSTCODE,"+" "+
    "DEV_BUREAU_NAME,"+" "+
    "DEV_SUB_BUREAU_NAME,"+" "+
    "CARD_TYPE,"+" "+
    "CARD_CODE,"+" "+
    "sex,"+" "+
    "age,"+" "+
    "CUSTOMER_TYPE,"+" "+
    "TOTAL_DATA date 'yyyy-MM-dd',"+" "+
    "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

  • 相关阅读:
    [网络流24题]餐巾计划问题
    [网络流24题]方格取数问题
    [网络流24题]试题库问题
    [网络流24题]最长递增子序列问题
    [网络流24题]圆桌问题
    [网络流24题]魔术球问题
    51nod1462 树据结构
    51nod1053 最大M子段和 V2
    51nod1026 矩阵中不重复的元素 V2
    BZOJ3832: [Poi2014]Rally
  • 原文地址:https://www.cnblogs.com/qq3245792286/p/6180452.html
Copyright © 2020-2023  润新知