C#实现SQL商品数量递减且禁止负值的解决方案
商品库存扣减的库存不足校验实现
需求:在商品扣减面板中,从SQL数据库扣减商品库存数量,若输入的扣减数大于当前库存导致库存变为负值时,需提示“库存不足”错误。
尝试代码(存在问题)
string constr = ConfigurationManager.ConnectionStrings["stok"].ConnectionString; SqlConnection con = new SqlConnection(constr); SqlCommand cmda; SqlCommand cmdb; con.Open(); SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM urunler WHERE barkod = '" + barkod.Text + "'", con); SqlDataAdapter db = new SqlDataAdapter("SELECT * FROM urunler WHERE adet >= '0' AND barkod = '" + barkod.Text + "'", con); DataSet ds = new DataSet(); DataSet dl = new DataSet(); da.Fill(ds); db.Fill(dl); if (ds.Tables[0].Rows.Count > 0) { cmda = new SqlCommand("UPDATE urunler SET cikarTarih='" + cikarTarih.Text + "'WHERE barkod='" + barkod.Text + "'", con); cmdb = new SqlCommand("UPDATE urunler SET adet=adet-1 WHERE barkod='" + barkod.Text + "'", con); for (int i = Convert.ToInt32(adet.Text); i > 0 ; i--) { cmdb.ExecuteNonQuery(); if (dl.Tables[0].Rows.Count < 0) { ClientScript.RegisterClientScriptBlock(this.GetType(), "K", "swal('Hata', 'Ürün adedi yeterli değil!', 'error')", true); } } cmda.ExecuteNonQuery(); ClientScript.RegisterClientScriptBlock(this.GetType(), "K", "swal('İşlem Tamamlandı', 'Ürün adedi başarıyla güncellendi!', 'success')", true); } else { ClientScript.RegisterClientScriptBlock(this.GetType(), "K", "swal('Hata', 'Aradığınız ürün bulunamadı!', 'error')", true); } con.Close();
原代码的问题
- 库存校验逻辑无效:
dl.Tables[0].Rows.Count < 0永远不会成立,因为查询结果的行数不可能为负数,导致库存不足的提示永远无法触发。 - 校验时机错误:先执行库存扣减操作,再判断库存是否足够,即使库存不足,扣减已经完成,会直接导致库存变为负值。
- 查询条件无意义:
adet >= '0'的条件无法判断当前库存是否能覆盖要扣减的数量。
修正后的解决方案代码
string constr = ConfigurationManager.ConnectionStrings["stok"].ConnectionString; SqlConnection con = new SqlConnection(constr); SqlCommand cmda; SqlCommand cmdb; con.Open(); SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM urunler WHERE barkod = '" + barkod.Text + "'", con); SqlDataAdapter db = new SqlDataAdapter("SELECT * FROM urunler WHERE adet >='" + Convert.ToInt32(adet.Text) + "'AND barkod = '" + barkod.Text + "'", con); DataSet ds = new DataSet(); DataSet dl = new DataSet(); da.Fill(ds); db.Fill(dl); if (ds.Tables[0].Rows.Count > 0) { if (dl.Tables[0].Rows.Count > 0) { cmda = new SqlCommand("UPDATE urunler SET cikarTarih='" + cikarTarih.Text + "'WHERE barkod='" + barkod.Text + "'", con); cmdb = new SqlCommand("UPDATE urunler SET adet=adet-1 WHERE barkod='" + barkod.Text + "'", con); for (int i = Convert.ToInt32(adet.Text); i > 0 ; i--) { cmdb.ExecuteNonQuery(); } cmda.ExecuteNonQuery(); ClientScript.RegisterClientScriptBlock(this.GetType(), "K", "swal('İşlem Tamamlandı', 'Ürün adedi başarıyla güncellendi!', 'success')", true); } else { ClientScript.RegisterClientScriptBlock(this.GetType(), "K", "swal('Hata', 'Yeterli ürün bulunamadı!', 'error')", true); } } else { ClientScript.RegisterClientScriptBlock(this.GetType(), "K", "swal('Hata', 'Aradığınız ürün bulunamadı!', 'error')", true); } con.Close();
改进点说明
- 提前校验库存:将查询条件改为
adet >= 输入的扣减数,先确认当前库存足够覆盖要扣减的数量,再执行扣减操作。 - 调整判断逻辑:通过
dl.Tables[0].Rows.Count > 0判断库存是否足够,若不足则直接提示错误,不执行扣减。 - 避免无效操作:只有库存校验通过后才执行循环扣减和日期更新,防止出现库存负值的情况。
额外提示:当前代码存在SQL注入风险,建议使用参数化查询替代字符串拼接的方式构建SQL语句,提升安全性。
内容的提问来源于stack exchange,提问作者Beyza Nur Karakaya
相关产品推荐
相关产品推荐

