如何通过在 java 中使用 Runtime.exec() 运行 sqlplus 来捕获 sqlplus 窗口的输出
Posted
技术标签:
【中文标题】如何通过在 java 中使用 Runtime.exec() 运行 sqlplus 来捕获 sqlplus 窗口的输出【英文标题】:How to capture output from sqlplus window by running sqlplus using Runtime.exec() in java 【发布时间】:2017-04-27 06:52:02 【问题描述】:我正在尝试从 java 运行 sql 脚本(此处为 memo_222dataFERG.out)并尝试从 sqlplus 窗口捕获输出。这是我的代码
Runtime rt = Runtime.getRuntime();
String runString1 = "cmd /c start sqlplus pecok/pecok@xe @C:\workspace\PeCok_Tool\memo_222dataFERG.out";
Process proc = null;
proc = rt.exec(runString1);
// proc = rt.exec("java -version");
InputStream is = proc.getErrorStream();
//InputStream is = proc.getInputStream();
int bufSize = 4096;
BufferedReader in = new BufferedReader(new InputStreamReader(is), bufSize);
String currentLine = null;
while ((currentLine = in.readLine()) != null)
System.out.println(" " + currentLine);
is.close();
int a = proc.waitFor();
System.out.println(" proc.waitFor() :: " +a);
Sqlplus 执行。 SQLPlus 窗口打开并开始执行我在 C:\workspace\PeCok_Tool\memo_222dataFERG.out 文件中编写的插入语句。但我无法从 sqlplus 窗口捕获输出并在 Eclipse 控制台中打印。在 while 循环中的某个地方它挂起并且没有在 Eclipse 控制台中打印任何内容。但是当我运行 "java -version"(在代码中注释)时,它成功地将 java 版本打印为控制台中的输出。现在我的问题是如何读取 sqlplus 窗口的输出?我尝试了 getErrorStream() 和 getInputStream()。
【问题讨论】:
如果直接从命令提示符运行命令会发生什么?您的脚本是否以“exit”结尾? 不...脚本中没有退出。 好吧,这是你的问题;如果您不退出,则 SQL*Plus 会坐在那里等待更多输入。 See this. 谢谢亚历克斯。我把退出放在脚本中。现在它工作正常。 Problem running oracle script from command line using sqlplus的可能重复 【参考方案1】:我知道您特别询问 sqlplus 和进程分叉,但是 SQLcl 运行 sqlplus 所做的任何事情,并且完全用 java 编写,因此易于集成。
我在这里有一个 github 存储库,专门针对如何执行此操作:https://github.com/oracle/oracle-db-tools/tree/master/sqlcl/java
这是其中一个 java 示例:
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import oracle.dbtools.raptor.newscriptrunner.ScriptExecutor;
import oracle.dbtools.raptor.newscriptrunner.ScriptRunnerContext;
public class RunMyScript
public static void main(String[] args) throws SQLException, UnsupportedEncodingException
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@//localhost:1521/XE", "klrice", "klrice");
conn.setAutoCommit(false);
// #create sqlcl
ScriptExecutor sqlcl = new ScriptExecutor(conn);
// #setup the context
ScriptRunnerContext ctx = new ScriptRunnerContext();
// #set the context
sqlcl.setScriptRunnerContext(ctx);
ctx.setBaseConnection(conn);
// Capture the results without this it goes to STDOUT
ByteArrayOutputStream bout = new ByteArrayOutputStream();
BufferedOutputStream buf = new BufferedOutputStream(bout);
sqlcl.setOut(buf);
// # run a whole file
// adjust the path as it needs to be absolute
sqlcl.setStmt("@/Users/klrice/workspace_commons/sqlcl-java/myfile.sql");
sqlcl.run();
String results = bout.toString("UTF8");
results = results.replaceAll(" force_print\n", "");
System.out.println(results);
【讨论】:
以上是关于如何通过在 java 中使用 Runtime.exec() 运行 sqlplus 来捕获 sqlplus 窗口的输出的主要内容,如果未能解决你的问题,请参考以下文章
如何通过在eclipse中使用指定的java路径目录而不是默认的Java路径来运行eclipse
如何在 Java 中使用 PSK 通过 MQTT 建立安全通信?
如何通过 onItemClickListener 在不同的类( ConsumerDescAndEdit.java )中使用某个类的变量?