在java中执行多个SQL语句

我想用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语句

您的代码中存在两个问题。 首先,使用相同的Statement对象( stmt )来执行select查询和insert。 在JDBC中,执行语句将关闭同一对象上一次执行的ResultSet

在代码中,循环遍历ResultSet并为每一行执行插入。 但是,执行该语句将关闭ResultSet ,因此在下一次迭代时,对next()的调用将在ResultSet关闭时抛出SQLException

解决方案是使用两个Statement对象:一个用于select,一个用于insert。 但是,默认情况下这并不总是有效,因为您正在使用autoCommit (这是默认设置),并且使用自动提交,任何语句的执行都将提交任何先前的事务(通常也会关闭ResultSet ,尽管这可能会有所不同)数据库和JDBC驱动程序)。 您需要禁用自动提交,或者将结果集创建为可保持提交(除非已经是JDBC驱动程序的默认设置)。

在模式的绝对或每个表中包含的数据中,我将做出以下假设:

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-resourcesfunction来确保数据库资源在完成后发布。
  • 您不需要执行Class.forName因为服务提供程序机制是在JavaDoc for DriverManager中详细介绍的。