如何使用ProcessBuilder运行MySQL脚本?

时间:2016-06-21 14:26:21

标签: java mysql

我有一个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来运行这样的脚本吗?

2 个答案:

答案 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可能更有意义。