2016-07-12 26 views
-1

Ich habe diesen Code, der Product to Products-Tabelle in der Datenbank hinzufügt, aber es fügt mehr als eine Zeile hinzu.Warum fügt dieser Code mehr als eine Zeile in die Datenbank ein?

Hier ist der Code:

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; 
} 

Wie Sie oben im Code sehen können, Ich überprüfe, ob ein Produkt in der Tabelle nicht vorhanden ist dann mit der Bestätigung ein. Es wird erfolgreich hinzugefügt, aber es fügt mehr als eine Zeile hinzu. Angenommen, ich habe das Produkt "ProductDao" initialisiert und es auf diese Weise getestet: productDAO.addProduct(new Products("Hotdogs", "Full", 55, new BigDecimal(0.30), "Box"), "Wing Yip");. Danach fügte es 14 davon ein, wie Sie in dem Bild unten sehen können.

14 Duplicate Rows

Weiß jemand, warum dies geschieht? Bitte lassen Sie mich wissen, danke.

+0

Ihr Insert fügt die Ergebnisse einer'Auswahl'-Anweisung ein - vielleicht möchten Sie das nicht? Und dieses 'select' ist nicht das selbe' select' wie du es gerade prüfst –

+0

@Scary Wombat Ist es das? Nun, ich möchte die 'supplier_id' einfügen und was du gesagt hast, ist nicht wirklich meine Absicht. Ist meine Aussage falsch? –

+1

versuchen, 'SELECT?,?, Suppliers.supplier_id,?,?,? FROM Produkte, Lieferanten WHERE products.supplier_id = Lieferanten.supplier_id UND Lieferanten.lieferanten_name =? ";' Getrennt und sehen, welche Ergebnisse erhalten Sie –

Antwort

0

Der zweite Teil Ihrer Insert-Anweisung ist eine select-Anweisung:

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

Dies hat die Fähigkeit, alle Datensätze zu wählen, dass die Lieferantennamen und die in beiden Tabellen erscheinen haben. Offensichtlich hat dieser Lieferant 14 Produkte, also werden so viele neue Datensätze eingefügt.

Um dies zu beheben, entfernen Sie die implizite JOIN. Es wird nicht für die supplier_id Suche benötigt.

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 = ? 
+0

So meine Aussage war richtig, aber mit 'LIMIT 1' hinzugefügt –

+0

Korrekt.Ein anderer Weg, um es zu lösen ist 'DISTINCT Lieferanten hinzufügen .supplier_id ", aber das macht die Abfrage mehr Arbeit als nötig. – 4castle

+0

Ich mag Ihre Antwort. Vielen Dank. Ich versuche wirklich INSERT INTO-Anweisungen zu machen, um den Code zu minimieren. Vielen Dank noch einmal. –

0

Dank @Scary Wombat und @ 4castle für die Hilfe. Ich habe jetzt eine separate Anweisung erstellt und mehr Code hinzugefügt, wie Sie unten sehen können.

//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"); 
} 

Dies löste mein Problem, aber ich versuche mit INSERT INTO SELECT Aussage, die es nicht wie erwartet funktioniert. Danke nochmal für die, die mir geholfen haben. :-)