如何使用sql loader将多个csv加载到多个表中

时间:2018-02-02 12:16:04

标签: java database spring oracle csv

我使用SQL loader将多个CSV文件加载到多个表中。 示例:我在Employee表中加载了 a.csv b.csv c.csv 文件,以及 d .csv e.csv f.csv 文件加载到Student表中。 我编写了一个Java脚本来实现SQL loader

@RestController
public class FileUploadController {
    // Using ServletContext
    @Autowired
    ServletContext context;

String folderUpload = context.getRealPath("/WEB-INF/uploaded");
            Process p = Runtime.getRuntime().exec(new String[] { "cmd", "/C", "all.bat" }, null,
                    new File(folderUpload));

            String sqlldrCmd = "Sqlldr baotrung/baotrung1192 control = " + folderUpload + "/full.ctl"
                    + "log=d:/bt.log skip=1";
            System.out.println(sqlldrCmd.replace("\\", "/"));
            System.out.println("SQLLDR Started ....... ");
            Runtime rt = Runtime.getRuntime();
            Process proc = rt.exec(sqlldrCmd.replace("\\", "/"));
            System.out.println(proc.waitFor());

            System.out.println("SQLLDR Ended ........  ");

我知道在SQL加载器中有一个加载选项:

load data
INFILE 'loader2.csv'
INTO TABLE articles_formatted
APPEND
FIELDS TERMINATED BY ','
(article_id SEQUENCE (MAX, 1),
 author CHAR (30)
 format,
 pub_date SYSDATE,
 title,
 ext_fname FILLER CHAR (80)
 text LOBFILE (ext_fname) TERMINATED BY EOF)

但是,如果我使用load data命令 INFILE仅将文件加载到表中。如果我想继续加载,我必须继续编写该命令。这是不可能的,因为我的系统有太多的CSV文件。我想知道将CSV文件加入单个CSV文件,但我的CSV文件用于多个表而不是一个表,因此工作此连接未实现。我有两个问题:

  1. 如何确定将哪个CSV文件加载到表中 CSV的数量是如此之大。我使CSV名称与表名匹配 但它不适合我的系统。

  2. 如何将多个CSV加载到多个表中。有办法吗? 将我的目录中的所有文件插入LOAD DATA INFILE 声明并逐一加载?

  3. 我已经编写了一个Java来解决这个问题,但它不能按顺序读取

    package com.baotrung;
    
    import java.io.File;
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.util.List;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    public class ListFile {
        public static void main(String[] args) {
            File dir = new File("E:\\xls");
            File[] files = dir.listFiles((d, name) -> name.endsWith(".csv"));
            for (File file : files) {
                file.getName();
            }
            Path content = Paths.get("E://xls//final.ctl");
            Stream<String> stream;
    
            try {
                stream = Files.lines(content);
                String line1 = Files.readAllLines(Paths.get("E://xls//final.ctl")).get(1);
                System.out.println(line1);
                List<String> replaced = stream.map(line -> line.replace(line1, files[0].getName().toString()))
                        .collect(Collectors.toList());
                Files.write(content, replaced);
                stream.close();
                System.out.println("Find and Replace done!!!");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    
    }
    

    代码执行目录中的CSV文件列表,然后打开 final.ctl 文件并执行CSV文件的内容。但我无法复制它以使文件夹中的文件周。 如何依次读取[0]文件中的文件。 请帮忙。

1 个答案:

答案 0 :(得分:0)

如果您合并了所有CSV文件,我建议您在第一列(或标识符)中设置区分记录的值。例如:

WHEN

然后您使用控制文件的 LOAD DATA INFILE ... INTO TABLE first WHEN identifier= 'first' (empno POSITION(1:4) INTEGER EXTERNAL, ename POSITION(6:15) CHAR, deptno POSITION(17:18) CHAR, mgr POSITION(20:23) INTEGER EXTERNAL) INTO TABLE second WHEN identifier= 'second' (empno POSITION(1:4) INTEGER EXTERNAL, projno POSITION(25:27) INTEGER EXTERNAL) INTO TABLE third WHEN identifier= 'third' (empno POSITION(1:4) INTEGER EXTERNAL, projno POSITION(29:31 INTEGER EXTERNAL) 子句(搜索&#34;根据条件加载记录&#34;,here)并指定哪个标识符&#39 ; s记录转到哪个表。以下示例是从Case Study 5: Loading data into multiple tables调整的:

{{1}}

我想它应该可以正常工作。此外,现在您知道要搜索的关键字(WHEN,MULTIPLE TABLES),以便您可以自己获取更多信息。祝你好运!