2011-04-27 73 views
1

我有一個sql腳本文件,我需要通過java執行存在的命令。我在網上搜索了相同的內容,我得到了一些定義解析器的代碼來分離SQL語句並執行它。但是他們都沒有爲我的SQL腳本文件工作。因爲我的腳本文件包含最終沒有分號的創建語句和alter語句[相反它有GO]任何人都可以建議一個解決方案來執行腳本文件? 謝謝, 馬赫什通過Java執行.sql文件

回答

1

對於簡單的腳本,我通常使用ibatis這個類 - ScriptRunner。另外,你可以從Java產生一個新的數據庫客戶端進程,並提供你想要執行的腳本。這將適用於所有腳本,因爲當例如sql文件中的分隔符被更改時,像ScriptRunner這樣的簡單解決方案不能很好地工作。

下面是一個例子如何餵養SQL作爲一個字符串轉換爲spawed DB客戶端進程:

private void runSql(String pSql) { 
     String tCommand = "mysql -u " + username + (password != null ? " -p" + password : "") + " " + dbName; 
     System.out.println(tCommand); 

     try { 
      Process tProcess = Runtime.getRuntime().exec(tCommand); 
      OutputStream tOutputStream = tProcess.getOutputStream(); 
      Writer w = new OutputStreamWriter(tOutputStream); 
      System.out.println(pSql); 
      w.write(pSql); 
      w.flush(); 

      Scanner in = new Scanner(tProcess.getErrorStream()); 

      String errorMessage = ""; 

      while (in.hasNext()) { 
       errorMessage += in.next() + " "; 
      } 

      if (errorMessage.length() > 0) { 
       System.out.println(errorMessage); 
       throw new ClientSqlExecutionException(errorMessage); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
+0

嘿感謝Bozhidar !!!我會回來到u嘗試這種代碼。 – Mahesh 2011-04-28 09:51:22

+0

嗨Bozhidar,我有一個包含MSSQL查詢的SQL腳本文件。在MSSQL執行通過我們SQLCMD命令,,, SQLCMD本身不通過上面的代碼工作的命令提示查詢!!!! – Mahesh 2011-04-28 10:40:55

+0

您應該調整它的參數。我從來沒有使用過它,但這種方法是通用的 - 用正確的命令行參數它會與任何分貝工作。 – 2011-04-28 10:50:48

0

您需要更改解析器所以它產生的可執行語句。但是我不確定當你說「通過Java執行」時我明白你的意思。

Java將不會執行這些SQL語句 - 您連接的數據庫將會執行。 Java可以使用JDBC連接到數據庫並從文件發送SQL語句。

我不明白爲什麼你必須解析SQL,除非你希望Java在將它們發送到數據庫服務器之前驗證它們。服務器會再次分析和驗證它們,所以感覺就像你在做額外的工作一樣。

0

我可以向您呈現的最簡單的解決方案就是假設我理解您的問題。

1)通過Java IO將文本文件讀入字符串或數組。 2)通過JDBC將字符串或數組傳遞給MySQL。

從文件中讀取例如,

import java.io.*; 
class FileRead 
{ 
    public static void main(String args[]) 
    { 
     try{ 
    // Open the file that is the first 
    // command line parameter 
    FileInputStream fstream = new FileInputStream("textfile.txt"); 
    // Get the object of DataInputStream 
    DataInputStream in = new DataInputStream(fstream); 
     BufferedReader br = new BufferedReader(new InputStreamReader(in)); 
    String strLine; 
    //Read File Line By Line 
    while ((strLine = br.readLine()) != null) { 
     // Print the content on the console 
     System.out.println (strLine); 
    } 
    //Close the input stream 
    in.close(); 
    }catch (Exception e){//Catch exception if any 
     System.err.println("Error: " + e.getMessage()); 
    } 
    } 
} 
從收購

http://www.roseindia.net/java/beginners/java-read-file-line-by-line.shtml

0

最簡單的方法是簡單地讓報表和檢查,如果他們需要,他們在最後半柱:(這是一個例如,如果是通過線語句只:

public void executeScript(String script) { 
    BufferedReader in = new BufferedReader(new FileReader(script)); 
    while (in.read() > 0) { 
    String statement = in.readLine(); 
    statement = statement.trim().toLowerCase(); 
    String command = statement.split("[ ]+")[0]; // split the statement. 

    if (command.equals("insert") || command.equals("update") /* || any other */) { 
     statement = statement + ";"; 
    } 

    // execute statement using jdbc 
    } 
} 

如果你不知道如何使用JDBC,只問:-)

+0

嘿感謝PIH ,,其實我的劇本沒有通過行語句,,它具有超過行語句! – Mahesh 2011-04-28 07:58:03

+0

你有某種語句分隔符嗎?可能會有所幫助。 – Pih 2011-04-28 08:40:24

+0

你我都有,它是 「GO」,這裏是我的腳本文件內容:USE [大師] GO /******對象:表[DBO] [Allowed_Countries]腳本日期:04/08/2011 17點22分四十秒******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [DBO]。[Allowed_Countries]( \t [國家或地區名稱] [VARCHAR( 100)NOT NULL, \t [CMName] [VARCHAR](100)NOT NULL, \t [允許] [字符](1)非空約束[DF_Allowed_Countries_Allowed] DEFAULT( 'Y') )ON [PRIMARY] GO SET ANSI_PADDING OFF GO ALTER TABLE [DBO] [Allowed_Countries]檢查約束[CK_Allowed_Countries] GO – Mahesh 2011-04-28 10:38:20

0

使用此slightly modified version of the com.ibatis.common.jdbc.ScriptRunner class這是完全獨立的,即你不需要有任何第三方依賴的JAR 。

可以將分隔符從;更改爲GO。我認爲應該這樣做。

下面是一個例子:

 Reader reader = new BufferedReader(*** Your FileReader instance ***); 
     try 
     { 
      ScriptRunner runner = new ScriptRunner(connection, false, true); 
      runner.setDelimiter("GO", true); 
      runner.runScript(reader); 
     } 
     finally 
     { 
      reader.close(); 
     } 
+0

嗨喬納斯,我試過上面的代碼!!!它不工作。這裏是我的腳本:USE [guru] GO /******對象:表[ 。DBO] [Allowed_Countries]腳本日期:04/08/2011 17時22分四十零秒******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [DBO] [Allowed_Countries]( \t [國家或地區名稱] [VARCHAR](100)NOT NULL, \t [CMName] [VARCHAR](100)NOT NULL, \t [允許] [字符](1)非空約束[DF_Allowed_Countries_Allowed]默認('Y') )ON [PRIMARY] GO SET ANSI_PADDING OFF GO ALTER TABLE [DBO]。[Allowed_Countries]檢查約束[CK_Allowed_Countries] GO – Mahesh 2011-04-28 07:59:55