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

如何解决如何使用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 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-