代码之家  ›  专栏  ›  技术社区  ›  Edward Khazzoum

为什么在H2数据库中创建表时出现错误4201-214?

  •  0
  • Edward Khazzoum  · 技术社区  · 1 年前

    我正在使用Java、spring boot和H2数据库进行一个Account Service项目,下一步是使用sql实现添加员工工资。

    这是供参考的相关代码:

      @PostMapping("/api/acct/payments")
        public ResponseEntity<?> postPayrolls(@Valid @RequestBody UserPayroll[] payrolls) throws SQLException {
            try (Connection connection = DriverManager.getConnection(url)) {
                connection.setAutoCommit(false);
                try (PreparedStatement createTable = connection.prepareStatement("CREATE TABLE IF NOT EXISTS payrolls(" +
                        "employee VARCHAR(20)," +
                        "period VARCHAR(20)," +
                        "salary INTEGER");
                        PreparedStatement statement = connection.prepareStatement(
                        "INSERT INTO payrolls (employee, period, salary) VALUES (?, ?, ?)" )) {
    
                    createTable.executeUpdate();
                    for (UserPayroll payroll : payrolls) {
                        statement.setString(1, payroll.getEmployee());
                        statement.setString(2, payroll.getPeriod());
                        statement.setLong(3, payroll.getSalary());
                        statement.executeUpdate();
                    }
                    connection.commit();
                } catch (SQLException e) {
                    System.out.println(e.getMessage());
                }
            } catch (SQLException e) {
                System.out.println("1 " + e.getMessage());
            }
            Map<String, String> response = new HashMap<>();
            response.put("status", "Added successfully!");
            return ResponseEntity.ok().body(response);
        }
    
    public class UserPayroll {
    
        private String employee;
        @Pattern(regexp = "^(0[1-9]|1[0-2])-(20\\d{2}|19\\d{2})$")
        private String period;
        @Min(1)
        private Long salary;
    
    //Constructors, Getters and Setters
    }
    

    这是我在尝试创建工资表时遇到的错误:

    SQL语句“CREATE TABLE IF NOT EXISTS payrollments(employee VARCHAR(20),period VARCHAR(20)、salary INTEGER[*]”中存在语法错误;应为“ARRAY,INVISIBLE,VISIBLE,NOT NULL,NULL,AS,DEFAULT,GENERATED,ON UPDATE,NOT NULL、NULL、AUTO_INCREMENT、DEFAULT ON NULL、NULL_TO_DEFAULT、SEQUENCE、SELECTIVITY、COMMENT、CONSTRAINT、COMMENT,PRIMARY KEY、UNIQUE、NOT NULL、NULL、CHECK、REFERENCES、AUTO_INCREMENT,)”;SQL语句: 如果不存在,则创建表格工资单(员工VARCHAR(20),期间VARCHAR(20)、工资整数[44201-214]

    当用户输入url时,他们必须提供一个UserPayrolls列表,然后必须将其添加到数据库中。但是,由于抛出了SQL异常,因此数据库中没有保存任何内容。

    0 回复  |  直到 1 年前
        1
  •  2
  •   Evgenij Ryazanov    1 年前

    您需要在此处添加右括号:

    "salary INTEGER)");
    

    您也不能创建此语句

    PreparedStatement statement = connection.prepareStatement(
                        "INSERT INTO payrolls (employee, period, salary) VALUES (?, ?, ?)" )) {
    

    之前 createTable.executeUpdate(); ,因为H2由于性能原因立即遵守了准备好的声明。您需要移动的初始化 statement 低于 createTable

    实际上,重新组织应用程序会更好,它应该在初始化期间在数据库中创建模式。不要将查询和数据修改命令与数据定义命令混合使用,这对任何应用程序来说都是个坏主意。