为什么此代码在数据库中插入多行?

时间:2016-07-12 00:39:34

标签: java mysql jdbc prepared-statement resultset

我有这个代码在数据库中添加Product to Products表,但它添加了多行。

以下是代码:

public int addProduct(Products product, String supplierName) {

    //find a product
    String checkAllProducts = "SELECT * FROM products WHERE product_name = ?";

    //Insert product and supplier id where supplier exist in suppliers table sql statement
    String insertSql = "INSERT INTO products (product_name, product_type, supplier_id, number_of_stocks, price_per_unit, packaging_type) SELECT ?,?,suppliers.supplier_id,?,?,? FROM  suppliers WHERE suppliers.supplier_name = ?";

    //Get connection
    Connection conn = DbUtil.getConnection();

    //Resultset for checking existing products
    ResultSet resultSet = null;

    int inserted = 0;

    try {

        //Prepare check all products statement
        allProducts = conn.prepareStatement(checkAllProducts);
        allProducts.setString(1, product.getProductName());
        resultSet = allProducts.executeQuery();

        //If doesn't exist in products table
        if (!resultSet.next()) {
            //Prepare insert statement
            addProduct = conn.prepareStatement(insertSql);
            //Get product parameter's data
            addProduct.setString(1, product.getProductName());
            addProduct.setString(2, product.getProductType());
            addProduct.setInt(3, product.getNumberOfStocks());
            addProduct.setBigDecimal(4, product.getPricePerUnit());
            addProduct.setString(5, product.getPackagingType());
            addProduct.setString(6, supplierName);

            //Confirm insert
            int confirmation = JOptionPane.showConfirmDialog(null, "Are you sure you want to insert this product?", "Insert Confirm", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
            if (confirmation == JOptionPane.YES_OPTION) {
                //execute insert
                inserted = addProduct.executeUpdate();
            }

        }//Else don't insert and show error messages.
        else {
            JOptionPane.showMessageDialog(null, "Product already exists.", "Invalid insert.", JOptionPane.ERROR_MESSAGE);
        }

    } catch (SQLException ex) {
        Logger.getLogger(ProductDAO.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        DbUtil.close(conn, allProducts, resultSet);
        DbUtil.close(conn, addProduct, resultSet);
    }

    return inserted;
}

正如您在上面的代码中所看到的,我正在检查表中是否存在产品,然后插入确认信息。它已成功添加,但它添加了多行。例如,假设我初始化了productDao对象,并以这种方式测试它:productDAO.addProduct(new Products("Hotdogs", "Full", 55, new BigDecimal(0.30), "Box"), "Wing Yip");。完成后,它会插入其中的14个,如下图中的图片链接所示;

14 Duplicate Rows

有谁知道为什么会这样?请让我知道谢谢。

2 个答案:

答案 0 :(得分:0)

感谢@Scary Wombat和@ 4castle的帮助。我现在所做的是创建一个单独的语句并添加更多代码,如下所示。

//find supplier
String checkSupplierQuery = "SELECT products.supplier_id FROM products, suppliers WHERE products.supplier_id = suppliers.supplier_id AND suppliers.supplier_name = ? ";

//Prepare check supplier statement
PreparedStatement checkSupplier = conn.prepareStatement(checkSupplierQuery);
checkSupplier.setString(1, supplierName);
resultSet = checkSupplier.executeQuery();

String supplier = "";
while (resultSet.next()) {
  supplier = resultSet.getString("products.supplier_id");
}

这解决了我的问题,但我尝试使用INSERT INTO SELECT语句,但它没有像我预期的那样工作。再次感谢那些帮助过我的人。 : - )

答案 1 :(得分:0)

insert语句的第二部分是select语句:

SELECT
    ?, ?,
    suppliers.supplier_id,
    ?, ?, ? 
FROM products, suppliers
WHERE 
    products.supplier_id = suppliers.supplier_id 
    AND suppliers.supplier_name = ?

这样就可以选择具有该供应商名称且出现在两个表中的所有记录。显然,供应商有14种产品,因此插入了多少新记录。

要解决此问题,请删除隐式JOINsupplier_id查找不需要它。

INSERT INTO products (
    product_name, 
    product_type,
    supplier_id,
    number_of_stocks,
    price_per_unit, 
    packaging_type
) SELECT 
    ?, ?,
    suppliers.supplier_id,
    ?, ?, ?
FROM suppliers
WHERE suppliers.supplier_name = ?