繁体   English   中英

如何将数据从一个表复制到另一个表,然后使用 Java 删除第一个表中的数据?

[英]How to copy data from one table to another and then delete that data in first table using Java?

数据库中有两个表,一个是包含 roll_no(PK)、name、grade 和 DOB 列的 Student 表,另一个包含 roll_no、name、grade 和 leave_date 列的 StudentLeft 表。

我想从用户输入的学生表中删除学生的记录,并将学生名、姓名、成绩和离开日期(记录被删除并添加到表中的日期)添加到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, name, standard, 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 (...)块中的代码完成执行时,连接和语句将关闭。

可以使用INSERT INTO ... SELECT语句一次性完成将数据从Student表传输到StudentLog表。 这个语句不返回任何结果集:没有什么可迭代的,我们只是执行它并插入行。

DELETE语句类似:它也不返回任何结果集。 我已经FROM惯例向其中添加了关键字FROM :正如在另一个答案中指出的那样, FROM是可选的。

我还将catch (SQLException e)块移到最后:它将处理连接到数据库或执行任一准备好的语句时生成的所有 SQLException。

我保留了尝试加载 Oracle 数据库驱动程序类的代码,但在catch块中添加了一个return语句:如果出现异常,则驱动程序不在类路径上并且连接到数据库肯定会失败,所以我们不妨停下来。 但是,对于最新版本的 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();
    }
}

然后应该 SELECT+INSERT 到数据库,使用一个语句(INSERT SELECT)。

StudentLog 的 SQL 对我来说有点难以理解,但一个不错的 INSERT 是:

INSERT INTO StudentLog VALUES(roll_no, name, standard)
SELECT roll_no, name, grade
FROM Student
WHERE roll_no = ?

消除对数据库访问的 Java 嵌套的需要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM