2016-06-21 88 views
1

我有一個SQL腳本,我想從一個運行在Windows上的Java類執行。目前我正在試圖在下面的函數來做到這一點使用ProcessBuilder如何使用ProcessBuilder運行MySQL腳本?

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

嘗試使用空格字符「-u」+ user,而不是「-u」+ user ... – andrii

+0

沒有區別,MySQL不關心用戶名(只是密碼)的空格:https:// dev。 mysql.com/doc/refman/5.5/en/command-line-options.html「對於需要值的簡短選項,選項值可以緊跟在選項字母之後,或者可以在」 – whrrgarbl

回答

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可能更有意義。

0

您需要添加數據庫名稱,也將努力ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "mysql", "-u"+user, "-p"+password,"dbname", " < "+ filename);

+0

「之間有一個空格問題在於命令行將該文件解釋爲數據庫名稱。腳本本身正在創建一個新的數據庫並向它添加表,所以我最初並不想或不想使用數據庫。當我使用你的命令時(使用一個已經存在的不同的數據庫名稱),這個過程就會掛起。 – whrrgarbl

+0

腳本可能包括創建dbname,但仍需要根據MySQL命令行文檔添加dbname im進程生成器。從腳本中刪除create dbname並嘗試按上述方式執行回答 –

+0

我試過,但程序只是掛起,直到我強制退出,無需運行腳本或打印任何東西。 (我懷疑它可能剛剛運行「mysql」並忽略了最後一個arg,不知道如何驗證,因爲沒有打印任何內容)。我使用腳本創建,因此也可以在不需要Java的情況下設置數據庫。 – whrrgarbl