2014-06-11 135 views
4

我想在Java中執行查詢。在java中執行多個SQL語句

我創建了一個連接。然後我想執行INSERT語句,完成後,連接關閉,但我想通過連接執行一些插入語句,並在循環完成後關閉連接。

我該怎麼辦?

我的示例代碼:

public NewClass() throws SQLException { 
    try { 
     Class.forName("oracle.jdbc.driver.OracleDriver"); 
    } catch (ClassNotFoundException e) { 
     System.out.println("Where is your Oracle JDBC Driver?"); 
     return; 
    } 
    System.out.println("Oracle JDBC Driver Registered!"); 

    Connection connection = null; 
    try { 
     connection = DriverManager.getConnection(
       "jdbc:oracle:thin:@localhost:1521:orcl1", "test", 
       "oracle"); 
    } catch (SQLException e) { 
     System.out.println("Connection Failed! Check output console"); 
     return; 
    } 

    if (connection != null) { 
     Statement stmt = connection.createStatement(); 
     ResultSet rs = stmt.executeQuery("SELECT * from test.special_columns"); 
     while (rs.next()) { 
      this.ColName = rs.getNString("column_name"); 
      this.script = "insert into test.alldata (colname) (select " + ColName + " from test.alldata2  ) " ; 
      stmt.executeUpdate("" + script); 
     }   
    } 
    else { 
     System.out.println("Failed to make connection!"); 
    }   
} 

當執行select語句("SELECT * from test.special_columns"),循環必須是兩次,但是當(stmt.executeUpdate("" + script))被執行和完成,然後關閉連接,並從返回類。

+1

是否有可能是您有異常? – Jens

+0

我不這麼認爲,因爲當我打印腳本並在sqlPlus上執行它們時,它們都可以,並且插入成功 –

+0

向循環中添加一些'System.out.println()'語句以查看發生了什麼或使用調試器。 – Jens

回答

4

以下示例使用addBatch & executeBatch命令可同時執行多個SQL命令。

import java.sql.*; 

public class jdbcConn { 
    public static void main(String[] args) throws Exception{ 
     Class.forName("org.apache.derby.jdbc.ClientDriver"); 
     Connection con = DriverManager.getConnection 
     ("jdbc:derby://localhost:1527/testDb","name","pass"); 
     Statement stmt = con.createStatement 
     (ResultSet.TYPE_SCROLL_SENSITIVE, 
     ResultSet.CONCUR_UPDATABLE); 
     String insertEmp1 = "insert into emp values 
     (10,'jay','trainee')"; 
     String insertEmp2 = "insert into emp values 
     (11,'jayes','trainee')"; 
     String insertEmp3 = "insert into emp values 
     (12,'shail','trainee')"; 
     con.setAutoCommit(false); 
     stmt.addBatch(insertEmp1); 
     stmt.addBatch(insertEmp2); 
     stmt.addBatch(insertEmp3); 
     ResultSet rs = stmt.executeQuery("select * from emp"); 
     rs.last(); 
     System.out.println("rows before batch execution= " 
     + rs.getRow()); 
     stmt.executeBatch(); 
     con.commit(); 
     System.out.println("Batch executed"); 
     rs = stmt.executeQuery("select * from emp"); 
     rs.last(); 
     System.out.println("rows after batch execution= " 
     + rs.getRow()); 
    } 
} 

結果: 上面的代碼樣品將產生如下結果result.The可能會發生變化。

rows before batch execution= 6 
Batch executed 
rows after batch execution= = 9 

來源:Execute multiple SQL statements

0

在架構的abscence或包含在每個表我要作如下假設數據:

special_columns看起來是這樣的:

column_name 
----------- 
column_1 
column_2 
column_3 

alldata2可能看起來像這樣的表:

column_1 | column_2 | column_3 
--------------------------------- 
value_1_1 | value_2_1 | value_3_1 
value_1_2 | value_2_2 | value_3_2  

alldata應,後鑲塊,正巧是這樣的:

colname 
--------- 
value_1_1 
value_1_2 
value_2_1 
value_2_2 
value_3_1 
value_3_2 

根據這些假設,你可以複製的數據是這樣的:

try (
    Connection connection = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl1", "test", "oracle") 
) 
{ 
    StringBuilder columnNames = new StringBuilder(); 

    try (
    Statement select = connection.createStatement(); 
    ResultSet specialColumns = select.executeQuery("SELECT column_name FROM special_columns"); 
    Statement insert = connection.createStatement() 
) 
    { 
    while (specialColumns.next()) 
    { 
     int batchSize = 0;    

     insert.addBatch("INSERT INTO alldata(colname) SELECT " + specialColumns.getString(1) + " FROM alldata2"); 

     if (batchSize >= MAX_BATCH_SIZE) 
     { 
     insert.executeBatch(); 
     batchSize = 0; 
     } 
    } 

    insert.executeBatch(); 
    } 

一對夫婦的事情注意:

  • MAX_BATCH_SIZE應設置爲值基於您的數據庫配置和正在插入的數據。
  • 此代碼使用Java 7 try-with-resources功能來確保數據庫資源在完成時釋放。
  • 由於service provider機制的引入,您無需執行Class.forName機制,詳見JavaDoc中的DriverManager
1

你的代碼有兩個問題。首先使用相同的Statement對象(stmt)執行選擇查詢和插入。在JDBC中,執行語句將關閉同一對象上先前執行的ResultSet

在您的代碼中,循環遍歷ResultSet併爲每行執行插入操作。但是執行該語句將關閉ResultSet,因此在下一次迭代中,next()的呼叫將在ResultSet關閉時拋出SQLException

解決方法是使用兩個Statement對象:一個用於選擇,一個用於插入。但是,默認情況下,這不會總是有效,因爲您正在使用autoCommit(這是默認設置),並且通過自動提交,任何語句的執行都會提交以前的任何事務(通常也會關閉ResultSet,儘管這可能會有所不同數據庫和JDBC驅動程序)。您需要禁用自動提交,或者將結果集創建爲可保留的提交(除非已經是您的JDBC驅動程序的默認值)。