You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何捕获SQL Loader执行异常?附Java REST调用场景

如何捕获SQL Loader的执行异常

你现在的代码只是启动了SQL Loader进程,但没有等待它执行完成,也没有捕获它的错误输出,所以根本没法知道SQL Loader是否执行失败。下面是具体的解决方法:

1. 等待进程执行完成并获取退出码

SQL Loader执行完成后会返回一个退出码:0表示成功,非0值表示执行出错(比如控制文件错误、数据格式错误等)。你需要用proc.waitFor()来等待进程结束,并获取这个退出码,以此判断执行结果。

2. 捕获SQL Loader的错误输出

SQL Loader的错误信息会输出到标准错误流(stderr),如果不读取这个流,不仅拿不到错误信息,还可能导致进程因为输出缓冲区满而阻塞。所以需要读取并保存错误流的内容,方便排查问题。

3. 结合日志文件获取详细信息

你已经指定了log=d:/bt.log,SQL Loader会把详细的执行日志(包括错误细节)写入这个文件,执行完成后可以读取这个文件的内容来获取更完整的错误上下文。


修改后的示例代码

@PostMapping("/getCsv")
public ResponseEntity<?> getAll() {
    try {
        String path = context.getRealPath("/WEB-INF/uploaded");
        // 注意去掉文件名后面的空格,避免命令解析出错
        String fileName = "sqlldr_Employees.ctl";
        String sqlldrCmd = "sqlldr trung/tbtrung control=" + path + "/" + fileName + 
                           " log=d:/bt.log skip=1 data=" + path + "/*.csv";
        String formattedCmd = sqlldrCmd.replace("\\", "/");
        System.out.println("执行命令:" + formattedCmd);
        System.out.println("SQLLDR Started ....... ");

        Runtime rt = Runtime.getRuntime();
        Process proc = rt.exec(formattedCmd);

        // 读取标准错误流(SQL Loader的错误信息会输出到这里)
        String errorOutput = new String(proc.getErrorStream().readAllBytes(), StandardCharsets.UTF_8);
        // 读取标准输出流(可能包含警告信息)
        String standardOutput = new String(proc.getInputStream().readAllBytes(), StandardCharsets.UTF_8);

        // 等待进程执行完成,获取退出码
        int exitCode = proc.waitFor();
        System.out.println("SQLLDR Ended ........ 退出码:" + exitCode);

        // 处理执行结果
        if (exitCode != 0) {
            // 执行失败,打印错误信息,也可以返回给前端
            System.err.println("SQL Loader执行出错:");
            System.err.println("标准输出:" + standardOutput);
            System.err.println("错误输出:" + errorOutput);
            
            // 读取日志文件获取更详细的错误内容
            File logFile = new File("d:/bt.log");
            String logContent = Files.readString(logFile.toPath(), StandardCharsets.UTF_8);
            System.err.println("日志文件详情:" + logContent);
            
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("数据导入失败,错误信息:" + errorOutput);
        }

        return ResponseEntity.status(HttpStatus.OK).body("数据导入成功");
    } catch (Exception e) {
        e.printStackTrace();
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("程序执行异常:" + e.getMessage());
    }
}

额外注意事项

  • 命令格式要严谨:比如你原来的fileName后面多了一个空格,会导致命令解析错误,一定要去掉这类多余空格。
  • 流读取兼容性:如果你的项目用的是Java 8及以下版本,不能直接用readAllBytes(),需要用BufferedReader逐行读取流内容。
  • 不要忽略标准输出:有时候SQL Loader的警告信息会输出到标准输出,这些信息也能帮你排查潜在问题。

内容的提问来源于stack exchange,提问作者BaoTrung Tran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:12:55