在java中执行多条SQL语句
Posted
技术标签:
【中文标题】在java中执行多条SQL语句【英文标题】:Execute multiple SQL statements in java 【发布时间】:2014-06-11 07:38:02 【问题描述】:我想在 Java 中执行查询。
我创建了一个连接。然后我想执行一个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)
)执行完毕,则关闭连接,从类中返回。
【问题讨论】:
你有可能遇到异常吗? 我不这么认为,因为当我打印脚本并为 sqlPlus 执行它们时,它们没问题并且插入成功 在循环中添加一些System.out.println()
语句以查看发生了什么或使用调试器。
我建议将 try/catch 放在你的循环周围 - 并打印你可能遇到的任何异常。可能会有一些你不太期待的事情。
【参考方案1】:
以下示例使用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());
结果: 上述代码示例将产生以下结果。结果可能会有所不同。
rows before batch execution= 6
Batch executed
rows after batch execution= = 9
来源:Execute multiple SQL statements
【讨论】:
【参考方案2】:在没有架构或每个表中包含的数据的情况下,我将做出以下假设:
表格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
,因为service provider 机制已在DriverManager 的JavaDoc 中详细介绍。
【讨论】:
【参考方案3】:您的代码中有两个问题。首先,您使用相同的 Statement
对象 (stmt
) 来执行选择查询和插入。在 JDBC 中,执行一条语句将关闭前一次在同一对象上执行的 ResultSet
。
在您的代码中,您循环遍历ResultSet
并为每一行执行插入操作。然而,执行该语句将关闭ResultSet
,因此在下一次迭代中,对next()
的调用将在ResultSet
关闭时抛出SQLException
。
解决方案是使用两个Statement
对象:一个用于选择,一个用于插入。然而,默认情况下这并不总是有效,因为您在autoCommit
中工作(这是默认设置),并且使用自动提交,任何语句的执行都将提交任何以前的事务(通常也会关闭ResultSet
,尽管这可能在数据库和 JDBC 驱动程序之间有所不同)。您要么需要禁用自动提交,要么将结果集创建为可通过提交保留(除非这已经是 JDBC 驱动程序的默认设置)。
【讨论】:
以上是关于在java中执行多条SQL语句的主要内容,如果未能解决你的问题,请参考以下文章
[mybatis] sql语句无错误,但是执行多条sql语句时,抛出java.sql.SQLSyntaxErrorException