数据库表创建失败求助:基于PreparedStatement与事务的Java代码排查
数据库表创建失败及数据导入问题排查修复
问题场景
练习使用PreparedStatement与事务,需创建n012345_Accounts表并从Accounts.txt导入数据,运行代码时控制台返回unable to create new table for accounts,无法完成表创建。
核心错误点及修复方案
1. DDL语句执行方法错误
- 问题:创建表属于DDL语句,不能用
executeQuery()执行(该方法仅用于SELECT等返回结果集的查询语句),会直接抛出SQLException。 - 修复:改用
executeUpdate()执行建表语句,无需ResultSet接收结果:stmt.executeUpdate("CREATE TABLE n012345_Accounts (...)");
2. Oracle语法与字段设计问题
- 问题:
- Oracle中
FLOAT(n)的写法不符合规范,且账号是整数类型,用FLOAT存储不合适; Lock是Oracle关键字,直接作为列名会导致语法错误;- 余额字段未保留小数位,不符合金额存储需求。
- Oracle中
- 修复:调整建表语句,修正类型与列名:
(将CREATE TABLE n012345_Accounts ( AccountNumber NUMBER(4), Name VARCHAR(25), Balance NUMBER(9,2), Locked VARCHAR(25) )Lock改为Locked,与文件中的列名保持一致,避免关键字冲突)
3. 文件读取逻辑缺陷
- 问题:
- 未跳过文件的表头行,直接解析会导致
Float.parseFloat(fields[0])抛出异常(表头"Number"无法转成浮点数); - 用
split(" ")分割会把连续空格拆成空元素,导致数组长度异常。
- 未跳过文件的表头行,直接解析会导致
- 修复:
- 先读取一行跳过表头;
- 用
split("\\s+")匹配任意空白字符分割,同时跳过空行:// 跳过表头 reader.readLine(); String line; con.setAutoCommit(false); while ((line = reader.readLine()) != null) { line = line.trim(); // 跳过空行 if (line.isEmpty()) continue; String[] fields = line.split("\\s+"); // 后续插入逻辑... }
4. 事务与异常处理不严谨
- 问题:
- 文件读取或数据插入出错时,未执行事务回滚;
- 异常捕获过于宽泛,仅打印模糊提示,无法定位具体错误原因。
- 修复:
- 在文件读取的异常块中添加回滚操作;
- 捕获SQLException时打印堆栈信息,便于排查:
catch (SQLException ex) { System.out.println("unable to create new table for accounts"); ex.printStackTrace(); // 打印具体异常信息 }
5. 笔误问题
代码中打印提示信息写的是n01494108_Accounts,与实际创建的n012345_Accounts不一致,需修正为一致的表名。
修正后的完整代码
//Create a GUI application for a bank //it should manage fund transfers from one account to another //1 //Start //@ the start up it should create a table name YourStudentNumber_Accounts ( n012345) //it should also populate this table with the information stored in the file provided ("Accounts.txt") //2 //Then the application will ask for //account number the funds are to be transferred from //amount to be transferred //account number funds are to be transferred to //3 //Upon exit the application will present the contents of the Accounts table in standard output //USE PREPARED STATEMENTS and TRANSACTIONS wherever appropriate //All exceptions must be handled import oracle.jdbc.pool.OracleDataSource; import java.io.*; import java.sql.*; public class Main { public static void main(String[] args) { OracleDataSource ods = new OracleDataSource(); try { ods.setURL("jdbc:oracle:thin:n012345/luckyone@calvin.humber.ca:1521:grok"); } catch (SQLException e) { System.out.println("Failed to initialize data source"); e.printStackTrace(); return; } try(Connection con = ods.getConnection()) { con.setAutoCommit(false); // 提前设置事务自动提交为false try (Statement stmt = con.createStatement()) { // 修正建表语句,改用executeUpdate执行 String createTableSql = "CREATE TABLE n012345_Accounts (" + "AccountNumber NUMBER(4), " + "Name VARCHAR(25), " + "Balance NUMBER(9,2), " + "Locked VARCHAR(25))"; stmt.executeUpdate(createTableSql); System.out.println("Table n012345_Accounts created successfully"); try (BufferedReader reader = new BufferedReader(new FileReader("Accounts.txt"))) { // 跳过表头行 reader.readLine(); String line; String insertSql = "INSERT INTO n012345_Accounts (AccountNumber, Name, Balance, Locked) VALUES(?,?,?,?)"; while ((line = reader.readLine()) != null) { line = line.trim(); if (line.isEmpty()) continue; // 跳过空行 String[] fields = line.split("\\s+"); try (PreparedStatement pstmt = con.prepareStatement(insertSql)) { pstmt.setInt(1, Integer.parseInt(fields[0])); // 账号用int更合适 pstmt.setString(2, fields[1]); pstmt.setDouble(3, Double.parseDouble(fields[2])); pstmt.setString(4, fields[3]); pstmt.executeUpdate(); } catch (Exception e) { System.out.println("Error inserting data: " + line); e.printStackTrace(); con.rollback(); // 插入出错回滚事务 return; } } con.commit(); System.out.println("Accounts.txt data was populated into the table n012345_Accounts"); } catch (Exception e) { System.out.println("unable to read the file."); e.printStackTrace(); con.rollback(); } } catch (SQLException ex) { System.out.println("unable to create new table for accounts"); ex.printStackTrace(); con.rollback(); } } catch (SQLException ex) { System.out.println("Failed to connect to database"); ex.printStackTrace(); } } }
内容的提问来源于stack exchange,提问作者DevSteph
相关产品推荐
相关产品推荐

