2015-10-31 170 views
0

我有一個表格INVENTORY,其中有2列[product(主鍵) - quantity]。我想在此表中插入一個產品的數量。如果存在行,則更新列,如果不存在則插入行

public boolean insertPackage(String product, int quantity) 
      throws SQLException, ClassNotFoundException { 

     System.out.println("Insert product to Invetory"); 
     boolean flag=false; 
     sq = "INSERT INTO INVENTORY VALUES (?, ?)"; 

     try {  
      Class.forName(typeDB); 
      c = DriverManager.getConnection(path);    
      stm = c.prepareStatement(sq); 

      PreparedStatement stm = c.prepareStatement(sq); 

      stm.setString(1, product); 
      stm.setInt(2, quantity); 
      int rowsAffected = stm.executeUpdate(); 

     } catch (SQLException e) { 
      //There is already a same product in the Inventory 
      flag = true; 
      System.out.println(e.getMessage()); 
     } finally { 
     if (stm != null) 
        stm.close(); 
     if (c != null) 
        c.close(); 
     }  

     return flag; //if the flag is true, then execute insert. 
    } 

如果它返回true,那麼我搜索該產品,檢索數量,然後用新數量更新表格。我想知道如果這樣我想,是檢查如何執行插入或有更好的方法的好方法。

回答

1

這不是來檢查產品的存在是因爲一個好辦法:

- 有許多其他的事情可以去錯(很多不同的SQLException,不僅PK違反了),你將結束一個真正的國旗。

- 您不應該使用異常來處理正常情況。

- 拋出和捕捉異常很慢。

嘗試這種情況:從INVENTORY通過產物使用計數

1)選擇:

select count(*) from INVENTORY where product = ? 

2)如果計數等於0,那麼執行插入

別的遞增量。

+0

1.你大概的意思'COUNT(*)',而不是cound 2.我如何檢查'count'?它是可變的嗎?就像'if(count == 0)'? – yaylitzis

+0

喜歡這個例子,我猜? http://jexp.ru/index.php/Java/Database_SQL_JDBC/PreparedStatement#Count_Records_Using_PreparedStatement – yaylitzis

+0

@yaylitzis是的,這是一個很好的例子 –

2

在您的特定情況下,最簡單的解決辦法是使用SQLite的INSERT OR REPLACE語法,就像這樣:

public static void main(String[] args) { 
    String connectionURL = "jdbc:sqlite:"; // in-memory database 
    try (Connection conn = DriverManager.getConnection(connectionURL)) { 
     // set up test data 
     try (Statement st = conn.createStatement()) { 
      st.execute("CREATE TABLE INVENTORY (product VARCHAR(10) PRIMARY KEY, quantity INT)"); 
      st.execute("INSERT INTO INVENTORY (product, quantity) VALUES ('one', 123)"); 
     } 
     System.out.println("Initial state:"); 
     dumpTable(conn); 

     // real code starts here 
     String sql = "INSERT OR REPLACE INTO INVENTORY (product, quantity) VALUES (?, ?)"; 
     try (PreparedStatement ps = conn.prepareStatement(sql)) { 
      ps.setString(1, "two"); // product is new, so it will insert 
      ps.setInt(2, 234); 
      ps.executeUpdate(); 
      System.out.println(); 
      System.out.println("First change:"); 
      dumpTable(conn); 

      ps.setString(1, "one"); // product already exists, so it will replace 
      ps.setInt(2, 999); 
      ps.executeUpdate(); 
      System.out.println(); 
      System.out.println("Second change:"); 
      dumpTable(conn); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(System.err); 
    }  

} 

private static void dumpTable(Connection conn) throws SQLException { 
    try (
      Statement st = conn.createStatement(); 
      ResultSet rs = st.executeQuery("SELECT product, quantity FROM INVENTORY ORDER BY product")) { 
     while (rs.next()) { 
      System.out.printf(
        "product \"%s\" - quantity: %d%n", 
        rs.getString("product"), 
        rs.getInt("quantity")); 
     } 
    } 
} 

然而,INSERT OR REPLACE在SQLite是真的只是刪除後插入,所以另一種解決方案是嘗試並先執行UPDATE,如果UPDATE不影響任何行,則執行INSERT。 (如果你傾向於做多的插入更更新,可能更有效。)

public static void main(String[] args) { 
    String connectionURL = "jdbc:sqlite:"; // in-memory database 
    try (Connection conn = DriverManager.getConnection(connectionURL)) { 
     // set up test data 
     try (Statement st = conn.createStatement()) { 
      st.execute("CREATE TABLE INVENTORY (product VARCHAR(10) PRIMARY KEY, quantity INT)"); 
      st.execute("INSERT INTO INVENTORY (product, quantity) VALUES ('one', 123)"); 
     } 
     System.out.println("Initial state:"); 
     dumpTable(conn); 

     // real code starts here 
     updateQuantity("two", 234, conn); 
     System.out.println(); 
     System.out.println("First update:"); 
     dumpTable(conn); 

     updateQuantity("one", 999, conn); 
     System.out.println(); 
     System.out.println("Second update:"); 
     dumpTable(conn); 

    } catch (Exception e) { 
     e.printStackTrace(System.err); 
    }  

} 

private static void updateQuantity(String theProduct, int newQuantity, Connection conn) throws SQLException { 
    int rowsAffected; 
    try (PreparedStatement psUpdate = conn.prepareStatement("UPDATE INVENTORY SET quantity=? WHERE product=?")) { 
     psUpdate.setInt(1, newQuantity); 
     psUpdate.setString(2, theProduct); 
     rowsAffected = psUpdate.executeUpdate(); 
    } 
    if (rowsAffected == 0) { 
     try (PreparedStatement psInsert = conn.prepareStatement("INSERT INTO INVENTORY (product, quantity) VALUES (?, ?)")) { 
      psInsert.setString(1, theProduct); 
      psInsert.setInt(2, newQuantity); 
      psInsert.executeUpdate(); 
     } 
    } 
} 

private static void dumpTable(Connection conn) throws SQLException { 
    try (
      Statement st = conn.createStatement(); 
      ResultSet rs = st.executeQuery("SELECT product, quantity FROM INVENTORY ORDER BY product")) { 
     while (rs.next()) { 
      System.out.printf(
        "product \"%s\" - quantity: %d%n", 
        rs.getString("product"), 
        rs.getInt("quantity")); 
     } 
    } 
} 

在這兩種情況下,我們看到:

Initial state: 
product "one" - quantity: 123 

First update: 
product "one" - quantity: 123 
product "two" - quantity: 234 

Second update: 
product "one" - quantity: 999 
product "two" - quantity: 234 
相關問題