2014-06-11 131 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驱动程序的默认值)。