Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
读取一个固定长度的基于位置的文件,并在Java中插入到oracle表中_Java_Sql_Rest_File_Jakarta Ee - Fatal编程技术网

读取一个固定长度的基于位置的文件,并在Java中插入到oracle表中

读取一个固定长度的基于位置的文件,并在Java中插入到oracle表中,java,sql,rest,file,jakarta-ee,Java,Sql,Rest,File,Jakarta Ee,目前,我正在研究一种通过Java读取454个字符/行的大型文件(至少50000行)的解决方案。根据要求,它是一个基于位置的文件,我们首先需要读取该文件,然后解析基于位置的值,并需要插入到表中。(表格的96列中至少插入96个位置) 我在解析之后接受了这个概念 [ INSERT ALL INTO<TABLE NAME> [COL1,COL2,COL3] Values [VAL1,VAL2,VAL3] INTO<TABLE NAME> [COL1

目前,我正在研究一种通过Java读取454个字符/行的大型文件(至少50000行)的解决方案。根据要求,它是一个基于位置的文件,我们首先需要读取该文件,然后解析基于位置的值,并需要插入到表中。(表格的96列中至少插入96个位置)

我在解析之后接受了这个概念

[ INSERT ALL INTO<TABLE NAME> [COL1,COL2,COL3] Values [VAL1,VAL2,VAL3]
                INTO<TABLE NAME> [COL1,COL2,COL3] Values [VAL1,VAL2,VAL3]
SELECT * FROM DUAL;]
但一旦我运行了代码,如果有40-50行代码,它就可以正常工作了。但不仅仅如此,我还遇到了异常。有人能和我分享运行代码的正确方法吗,这样我就可以使用它了。
首先,请不要使用字符串连接来构建包含外部文本值的SQL语句。它使您容易受到攻击,并可能导致SQL语法错误。改用带有
参数标记的

其次,如果要插入大量记录,请使用JDBC批处理

以下是您将如何使用它的示例:

String sql = "INSERT INTO MyTable" +
            " ( Col1, Col2, Col3, Col4, Col5, Col6, Col7 )" +
            " VALUES (?,?,SYSDATE,?,?,?,?)";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
    char[] line = new char[456];
    int batchSize = 0;
    while (br.read(line) > 0) {
        String input = new String(line);
        int detailFileId = interfaceFileSequence();
        stmt.setInt   (1, detailFileId);
        stmt.setInt   (2, interfaceHeaderId);
        stmt.setInt   (3, interfaceRunId);
        stmt.setString(4, toString(input.substring(0, 2)));
        stmt.setDate  (5, toDate(input.substring(2, 12)));
        stmt.setString(6, toString(input.substring(12, 22)));
        // ...
        stmt.addBatch();
        if (++batchSize == 1000) {
            stmt.executeBatch();
            batchSize = 0;
        }
    }
    if (batchSize != 0) {
        stmt.executeBatch();
    }
} catch (IOException e) {
    e.printStackTrace();
}
上述代码使用以下帮助器方法保留代码:


有什么例外?发布堆栈跟踪。出现超时异常。此外,我们正在从REST-WS调用此函数。可能需要将代码移动到异步任务,以便REST调用可以立即返回,其中初始调用将返回一个“started”响应。然后提供另一个REST端点,客户端可以在其中偶尔调用以获取状态/进度。是。这是个好建议。但在这个加载之后,我们需要基于加载结果的其他进程,以及客户端如何获得加载是否完成的信息。此外,还有更好的解析和插入方法。状态端点返回当前进度,例如属性status为“working”、“completed”和“error”的JSON,以及可由客户端显示的processedCount。加载任务的结束可能会触发另一个异步任务,或者将任务安排在将来某个时间运行。另一部分是应该发布的代码审查。我同意这些建议,只是我会使用
stmt.setObject()
设置一个现代的
LocalDate
,而不是老式的
java.sql.Date
。这也将在
toDate()
中为您保存一个转换。
String sql = "INSERT INTO MyTable" +
            " ( Col1, Col2, Col3, Col4, Col5, Col6, Col7 )" +
            " VALUES (?,?,SYSDATE,?,?,?,?)";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
    char[] line = new char[456];
    int batchSize = 0;
    while (br.read(line) > 0) {
        String input = new String(line);
        int detailFileId = interfaceFileSequence();
        stmt.setInt   (1, detailFileId);
        stmt.setInt   (2, interfaceHeaderId);
        stmt.setInt   (3, interfaceRunId);
        stmt.setString(4, toString(input.substring(0, 2)));
        stmt.setDate  (5, toDate(input.substring(2, 12)));
        stmt.setString(6, toString(input.substring(12, 22)));
        // ...
        stmt.addBatch();
        if (++batchSize == 1000) {
            stmt.executeBatch();
            batchSize = 0;
        }
    }
    if (batchSize != 0) {
        stmt.executeBatch();
    }
} catch (IOException e) {
    e.printStackTrace();
}
private static String toString(String text) {
    String trimmed = text.trim();
    return (trimmed.isEmpty() ? null : trimmed);
}
private static java.sql.Date toDate(String text) {
    String trimmed = text.trim();
    return (trimmed.isEmpty() ? null : java.sql.Date.valueOf(LocalDate.parse(trimmed)));
}