如何捕获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
相关产品推荐
相关产品推荐

