簡體   English   中英

在java中執行多個SQL語句

[英]Execute multiple SQL statements in java

我想用Java執行查詢。

我創建了一個連接。 然后我想執行一個INSERT語句,完成后,連接關閉,但我想通過連接執行一些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) ),然后關閉連接並從類返回。

以下示例使用addBatchexecuteBatch命令同時執行多個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());
   }
} 

結果:上面的代碼示例將產生以下結果。結果可能會有所不同。

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

來源: 執行多個SQL語句

在模式的絕對或每個表中包含的數據中,我將做出以下假設:

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功能來確保數據庫資源在完成后發布。
  • 您不需要執行Class.forName因為服務提供程序機制是在JavaDoc for DriverManager中詳細介紹的。

您的代碼中存在兩個問題。 首先,使用相同的Statement對象( stmt )來執行select查詢和插入。 在JDBC中,執行語句將關閉同一對象上一次執行的ResultSet

在代碼中,循環遍歷ResultSet並為每一行執行插入。 但是,執行該語句將關閉ResultSet ,因此在下一次迭代時,對next()的調用將在ResultSet關閉時拋出SQLException

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM