我有一个SQL脚本,我想从在Java上运行的Java类执行。我目前正在尝试使用以下函数中的ProcessBuilder
执行此操作:
public static boolean runSqlScript(String filename, String user, String password) {
ProcessBuilder pb = new ProcessBuilder("mysql", "-u"+user, "-p"+password, "< "+ filename);
try {
Process pr = pb.start();
BufferedReader errors = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
BufferedReader output = new BufferedReader(new InputStreamReader(pr.getInputStream()));
while (pr.isAlive()) {
try {
System.err.println(errors.readLine());
System.out.println(output.readLine());
Thread.sleep(10);
} catch (InterruptedException e) {
break;
}
}
System.err.println(errors.readLine());
System.out.println(output.readLine());
int status = pr.exitValue();
return (status == 0);
} catch (IOException e) {
System.err.println("Error running command: " + e.getMessage());
return false;
}
}
文件名是脚本的绝对路径,验证用户和密码是否正确。但是当我运行它时,我得到错误:
ERROR 1102 (42000): Incorrect database name '< c:/path/to/script.sql'
为什么将它解释为数据库名称而不是命令行参数?我可以使用ProcessBuilder来运行这样的脚本吗?
答案 0 :(得分:0)
您需要添加数据库名称,它将起作用ProcessBuilder pb =
new ProcessBuilder("cmd", "/c", "mysql", "-u"+user, "-p"+password,"dbname", " < "+ filename);
答案 1 :(得分:0)
Runtime.exec()
也可用于发送命令,这与ProcessBuilder
似乎没有相同的问题:
public static boolean runSqlScriptRuntime(String filename, String user, String password) {
Runtime rt = Runtime.getRuntime();
try {
String cmd = "cmd /c mysql -u " + user + " -p" + password + " < " + filename;
System.out.println(cmd);
Process pr = rt.exec(cmd);
BufferedReader errors = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
BufferedReader output = new BufferedReader(new InputStreamReader(pr.getInputStream()));
while (pr.isAlive()) {
try {
System.err.println(errors.readLine());
System.out.println(output.readLine());
Thread.sleep(10);
} catch (InterruptedException e) {
break;
}
}
System.err.println(errors.readLine());
System.out.println(output.readLine());
int status = pr.exitValue();
return (status == 0);
} catch (IOException e) {
System.err.println("Error running command: " + e.getMessage());
return false;
}
}
尝试模拟命令行参数的另一种方法是从mysql内部调用SQL脚本,如here所述。
public static boolean runSqlScript(String filename, String user, String password) {
ProcessBuilder pb = new ProcessBuilder("mysql", "-u"+user, "-p"+password);
try {
Process pr = pb.start();
BufferedReader errors = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
BufferedReader output = new BufferedReader(new InputStreamReader(pr.getInputStream()));
BufferedWriter input = new BufferedWriter(new OutputStreamWriter(pr.getOutputStream()));
input.write("source " + filename + ";");
input.flush();
input.write("quit;");
input.flush();
input.close();
while (pr.isAlive()) {
try {
System.err.println(errors.readLine());
System.out.println(output.readLine());
Thread.sleep(10);
} catch (InterruptedException e) {
break;
}
}
System.err.println(errors.readLine());
System.out.println(output.readLine());
int status = pr.exitValue();
return (status == 0);
} catch (IOException e) {
System.err.println("Error running command: " + e.getMessage());
return false;
}
}
这将运行MySQL,然后调用脚本。但是,我最初使用ProcessBuilder
因为我认为脚本可以在一个命令行中处理 - 使用这样的解决方案,使用JDBC可能更有意义。