You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:05:57