如何解决如何使用Java将数据从一个表复制到另一个表,然后在第一个表中删除该数据?
数据库中存在两个表,一个表是带有roll_no(PK),名称,成绩和DOB列的Student表,另一个表是StudentLeft带有roll_no,名称,成绩和离开日期的列。
我要从用户输入其名册编号的学生表中删除该学生的记录,并添加名册编号,姓名,成绩和离开日期(删除记录并将其添加到表中的日期)到StudentLeft表。
这是我的方法。
public static void main(String[] args) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null,preparedStatement1 = null,preparedStatement2 = null;
ResultSet resultSet = null;
String selectQuery = "",updateQuery = "",deleteQuery = "";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
connection = dataSource.getConnection();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch (SQLException e) {
e.printStackTrace();
}
int rollNo = Integer.parseInt(args[0]);
try {
selectQuery = "SELECT name,grade FROM Student WHERE roll_no = ?";
updateQuery = "INSERT INTO StudentLog values WHERE roll_no = ?,name = ?,standard = ?";
deleteQuery = "DELETE Student WHERE roll_no = ?";
connection.setAutoCommit(false);
preparedStatement = connection.prepareStatement(selectQuery);
preparedStatement.setInt(1,rollNo);
resultSet = preparedStatement.executeQuery();
preparedStatement1 = connection.prepareStatement(updateQuery);
preparedStatement1.setInt(1,rollNo);
while (resultSet.next()) {
String name = resultSet.getString("name");
String grade = resultSet.getString("grade");
preparedStatement1.setString(2,name);
preparedStatement1.setString(3,grade);
preparedStatement1.addBatch();
}
preparedStatement1.executeBatch();
preparedStatement2 = connection.prepareStatement(deleteQuery);
preparedStatement.setInt(1,rollNo);
connection.commit();
}
catch (SQLException e) {
e.printStackTrace();
}
try {
if (!preparedStatement.isClosed() || !preparedStatement1.isClosed() || !preparedStatement2.isClosed()) {
preparedStatement.close();
preparedStatement1.close();
preparedStatement2.close();
}
if (!connection.isClosed())
connection.close();
}
catch (SQLException e) {
e.printStackTrace();
}
}
这些是错误。
java.sql.BatchUpdateException: ORA-00936: missing expression
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10500)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:230)
at Q3.main(Q3.java:48)
Exception in thread "main" java.lang.NullPointerException
at Q3.main(Q3.java:62)
我正在使用Oracle 11g Express数据库。
解决方法
您的查询不是
DELETE FROM Student WHERE roll_no = ?
代替
DELETE Student WHERE roll_no = ?
,
您编写的代码可以大大简化:
public static void main(String[] args) {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}
int rollNo = Integer.parseInt(args[0]);
try (Connection connection = dataSource.getConnection()) {
connection.setAutoCommit(false);
String transferStatement = "INSERT INTO StudentLog (roll_no,name,standard,leaving_date) " +
"SELECT roll_no,SYSDATE FROM Student WHERE roll_no = ?";
try (PreparedStatement stmt = connection.prepareStatement(transferStatement)) {
stmt.setInt(1,rollNo);
stmt.executeUpdate();
}
String deleteStatement = "DELETE FROM Student WHERE roll_no = ?";
try (PreparedStatement stmt = connection.prepareStatement(deleteStatement)) {
stmt.setInt(1,rollNo);
stmt.executeUpdate();
}
connection.commit();
}
catch (SQLException e) {
e.printStackTrace();
}
}
我使用了try-with-resources语句,该语句简化了对连接和准备好的语句的清理:try (...)
块中的代码完成执行后,连接和语句将关闭。
可以使用Student
语句一次性将数据从StudentLog
表传输到INSERT INTO ... SELECT
表。该语句不返回任何结果集:没有要迭代的结果,我们只执行它就可以插入行。
DELETE
语句类似:它也没有返回结果集。我在关键字FROM
中添加了关键字FROM
,这比以往任何时候都更为重要:正如另一个答案所指出的那样,catch (SQLException e)
是可选的。
我还将return
块移到了最后:它将处理在连接到数据库或执行任何准备好的语句时生成的所有SQLException。
我保留了尝试加载Oracle数据库驱动程序类的代码,但在catch
块中添加了'catid='+val
语句:如果发生异常,则驱动程序不在类路径中并确保连接到数据库失败,因此我们最好停止。但是,对于最新版本的Oracle驱动程序,您不需要进行此检查。尝试一下:查看代码是否在不经过此检查的情况下工作,如果可以,请将其删除。
您的DELETE代码使用了错误的预处理语句,缺少执行。
建议如下使用try-with-resources来自动关闭, 即使是返回或例外情况。 (它也照顾可变范围。)
public static void main(String[] args) throws SQLException {
int rollNo = Integer.parseInt(args[0]);
// Better statements possible.
final String selectQuery = "SELECT name,grade FROM Student WHERE roll_no = ?";
final String updateQuery =
"INSERT INTO StudentLog VALUES WHERE roll_no = ?,name = ?,standard = ?";
final String deleteQuery = "DELETE FROM Student WHERE roll_no = ?";
try { // Check whether you need this. It is for the old discovery mechanism.
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch (ClassNotFoundException e) {
throw new IllegalStateException("Database driver not provided",e);
}
try (Connection connection = dataSource.getConnection()) {
connection.setAutoCommit(false);
try (PreparedStatement preparedStatement =
connection.prepareStatement(selectQuery)) {
preparedStatement.setInt(1,rollNo);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
try (PreparedStatement preparedStatement1 =
connection.prepareStatement(updateQuery)) {
preparedStatement1.setInt(1,rollNo);
while (resultSet.next()) {
String name = resultSet.getString("name");
String grade = resultSet.getString("grade");
preparedStatement1.setString(2,name);
preparedStatement1.setString(3,grade);
preparedStatement1.addBatch();
}
preparedStatement1.executeBatch();
}
}
}
try (PreparedStatement preparedStatement2 =
connection.prepareStatement(deleteQuery)) {
preparedStatement2.setInt(1,rollNo); // NOT preparedStatement
preparedStatement2.executeUpdate();
}
connection.commit();
}
}
然后应该使用一条语句(INSERT SELECT)对数据库进行SELECT + INSERT。
StudentLog的SQL对我来说有点难以理解,但是一个不错的INSERT将是:
INSERT INTO StudentLog VALUES(roll_no,standard)
SELECT roll_no,grade
FROM Student
WHERE roll_no = ?
不再需要对数据库访问进行Java嵌套。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。