SQL : 车辆被添加到数据库但不是他的选项

SQL : Vehicule gets added to DataBase but not his options

这道题是这道题的延续:

我没有再抛出任何异常。数据被添加到 vehicule table 但没有添加到 vehicule_option table.

你知道为什么吗?

public boolean create(Vehicule v){
    String query = "INSERT INTO vehicule (MARQUE, MOTEUR, PRIX, NOM) VALUES (";
    query += v.getMarque().getId() + ", "
            + v.getMoteur().getId() + ", "
            + v.getPrix() + ", \'"
            + v.getNom() + "\');";

    try{
        connect.setAutoCommit(false);
        ResultSet nextID = connect.prepareStatement("CALL NEXT VALUE FOR seq_vehicule_id").executeQuery();
        if (nextID.next()){
            int ID = nextID.getInt(1);
            v.setId(ID-1);
        }

        for (Option o : v.getOptions()){
            System.out.println(v.getId() + " " + o.getId());
            query += "INSERT INTO vehicule_option (id_vehicule, id_option) VALUES ("
                    + v.getId() + ", " + o.getId() + ");";
        }

        Statement state = this.connect.createStatement();
        ResultSet rs = state.executeQuery(query);

    } catch (SQLException e){
        e.printStackTrace();
    }

    return true;
}

这是我使用此代码获得的查询示例:

INSERT INTO vehicule (MARQUE, MOTEUR, PRIX, NOM) VALUES (0, 0, 250.0, 'test');
INSERT INTO vehicule_option (id_vehicule, id_option) VALUES (34, 0);
INSERT INTO vehicule_option (id_vehicule, id_option) VALUES (34, 1);
INSERT INTO vehicule_option (id_vehicule, id_option) VALUES (34, 2);
INSERT INTO vehicule_option (id_vehicule, id_option) VALUES (34, 3);
INSERT INTO vehicule_option (id_vehicule, id_option) VALUES (34, 4);

我希望

std.execute(sql); 

每次你想插入东西的时候,executeQuery是针对"SELECT" ResultSet,

我给出一些改进代码的建议

  1. 将语句放在 try catch 之外(你需要在 finally 上关闭它)。

  2. 每次你想插入时使用statement.execute(sql)。 (因此,您将在循环之前有一个用于插入车辆,在循环内部有一个用于所有 vehicule_option(这也可以使用准备好的语句进行改进,但让我们暂时保留它)。

  3. 要获取插入记录的 ID 搜索 statement generated keys,并不是说您的方法不起作用,但这样可以避免查询(如果数据库支持生成的键)

我看到的问题是,当您第一次 CALL NEXT VALUE FOR seq_vehicule_id 获得一个 ID,但它与 vehicule_option 的 ID 不同。

在你旁边做一个 (ID-1) dont know why? 接下来要执行的是 INSERT INTO vehicule 也会生成一个新的 seq_vehicule_id

因此,如果您从 seq_id = 10 开始,那么 next value 将是 11 您将获得 id-1 -> 10 作为选项...而 INSERT INTO vehicule 将使用 12

所以我建议使用 vehicule_idINSERT INTO vehicule values (Vehicule_Id 而不是使用默认值。

如果您能向我们展示 query 的最终字符串,那就太好了。与其他评论不同,我认为您可以毫无问题地执行 query1; query2;。但是使用最终的查询字符串,您可以直接在数据库上验证语法是否正确。

请在下面找到更新后的代码。查看内联评论:

public boolean create(Vehicule v) {
        String query = "INSERT INTO vehicule (MARQUE, MOTEUR, PRIX, NOM) VALUES (";
        query += v.getMarque().getId() + ", " + v.getMoteur().getId() + ", "
                + v.getPrix() + ", \'" + v.getNom() + "\')";

        try {
            connect.setAutoCommit(false);
            ResultSet nextID = connect.prepareStatement(
                    "CALL NEXT VALUE FOR seq_vehicule_id").executeQuery();
            if (nextID.next()) {
                int ID = nextID.getInt(1);
                v.setId(ID - 1);
            }

            /* Save vehicle */
            Statement state = this.connect.createStatement();
            state.executeUpdate(query);

            /* Now start with creating query for vehicle_option. Execute only if collection not empty */
            if (!v.getOptions().isEmpty()) {
                query = "INSERT INTO vehicule_option (id_vehicule, id_option) VALUES ";
                boolean valueAdded = false;
                for (Option o : v.getOptions()) {
                    System.out.println(v.getId() + " " + o.getId());
                    if (valueAdded) {
                        query += ", ";
                    }
                    query += "(" + v.getId() + ", " + o.getId() + ")";
                    valueAdded = true;
                }

                state = this.connect.createStatement();
                state.executeUpdate(query);
            }
            /* Commit inserts if all queries executed fine */
            connect.commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return true;
    }

建议您将字符串连接替换为 StringBuilder 以构建查询。