Java Netbeans中如何通过单个按钮执行两条SQL Update语句?
如何通过一个按钮正确执行两条SQL Update语句?
我看了你的代码,发现问题出在两条Update语句的执行逻辑和顺序上:你先执行了减去库存的sql1,紧接着又执行了添加库存的sql,这相当于第二次更新直接覆盖了第一次的结果,最后库存只会变成pv + value,减库存的操作完全没生效。
其实根本不需要两条Update语句,我们可以把加减逻辑合并成一次计算,用单条Update完成操作,同时还能避免SQL注入风险,代码也更简洁。下面是具体的修复方案:
核心问题分析
你当前的代码逻辑是:
- 先把库存更新为
pv - value1 - 立刻又把库存更新为
pv + value
这就导致第一次的更新被完全覆盖,所以只有添加库存的效果生效。
修复步骤
1. 合并库存计算逻辑
正确的最终库存应该是 原有库存 + 新增数量 - 删除数量,也就是 pv + value - value1,不需要分开计算两个中间值。
2. 替换字符串拼接SQL,使用PreparedStatement参数占位符
你现在直接拼接字符串生成SQL的做法存在严重的SQL注入风险,而且代码可读性差。改用?作为参数占位符,通过setInt()等方法设置参数才是标准做法。
3. 使用try-with-resources自动管理资源
Java的try-with-resources语法可以自动关闭Connection、PreparedStatement等资源,避免手动关闭时可能出现的资源泄漏问题。
修改后的完整代码
private void Update_btnActionPerformed(java.awt.event.ActionEvent evt) { if (txt_add.getText().isEmpty() && txt_delete.getText().isEmpty()) { JOptionPane.showMessageDialog(null, "Enter Stock value"); return; } String url = "jdbc:sqlserver://localhost:1433;databaseName=InventoryTrackdb"; String un = "sa"; String pass = "123"; try (Connection conn = DriverManager.getConnection(url, un, pass)) { // 获取当前库存 int currentStock = Integer.parseInt(Table_stock.getValueAt(Table_stock.getSelectedRow(), 3).toString()); // 解析新增/删除数量,空值则设为0 int addQty = txt_add.getText().isEmpty() ? 0 : Integer.parseInt(txt_add.getText()); int deleteQty = txt_delete.getText().isEmpty() ? 0 : Integer.parseInt(txt_delete.getText()); // 计算最终库存 int finalStock = currentStock + addQty - deleteQty; // 检查库存是否为负 if (finalStock < 0) { JOptionPane.showMessageDialog(null, "Negative Stock"); clear_text(); return; } // 准备带参数的SQL语句 String sql = "UPDATE Add_item SET Stock = ? WHERE Itemcode = ? AND Itemname = ?"; try (PreparedStatement pst = conn.prepareStatement(sql)) { // 设置参数:注意参数索引从1开始 pst.setInt(1, finalStock); pst.setString(2, txt_id.getText()); pst.setString(3, txt_name.getText()); // 执行更新 int affectedRows = pst.executeUpdate(); if (affectedRows > 0) { update_table(); JOptionPane.showMessageDialog(null, "Updated Successfully"); clear_text(); } else { JOptionPane.showMessageDialog(null, "No matching item found to update"); } } } catch (SQLException ex) { Logger.getLogger(Main_stock.class.getName()).log(Level.SEVERE, null, ex); JOptionPane.showMessageDialog(null, "Update failed: " + ex.getMessage()); } }
关键细节说明
- 合并计算:通过
currentStock + addQty - deleteQty直接得到最终库存,一次更新就完成所有操作,避免了多次更新的覆盖问题。 - 参数化SQL:用
?占位符代替字符串拼接,既安全又易维护。 - 资源自动管理:
try (Connection conn = ...)和try (PreparedStatement pst = ...)会在代码块结束后自动关闭资源,无需手动调用close()。 - 新增结果检查:通过
executeUpdate()返回的受影响行数,判断是否真的有数据被更新,给用户更准确的反馈。
如果你确实需要执行两条独立的Update语句(比如业务逻辑要求必须分开),那你需要确保两条语句的逻辑不会互相覆盖,或者使用事务来保证操作的原子性,但在这个场景下,合并成一条语句显然是更优的方案。
内容的提问来源于stack exchange,提问作者blugren
相关产品推荐
相关产品推荐

