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

C#中DataGridView更新SQL Server双表数据异常求助

解决PurchaseInvoiceDetails更新时新增条目无法保存的问题

兄弟,你的问题根源一眼就能看出来:你现在只在用UPDATE语句处理明细,但UPDATE只能修改数据库里已存在的记录。当你在DataGridView里新增一条订单明细时,这条记录在PurchaseInvoiceDetails表中根本不存在,UPDATE语句找不到匹配的行,自然不会把它保存进去。而当只有一条数据时,那条数据是原本就存在的,所以UPDATE能正常生效。

给你两个实用的解决方案,按需选择:

方案一:删除旧明细 + 重新插入所有当前明细(简单易实现)

这种方式适合订单明细数量不多的场景,逻辑简单不容易出错:

  1. 首先删除该订单下所有已有的明细记录(确保和DataGridView的数据完全同步)
    DELETE FROM [dbo].[PurchaseInvoiceDetails] WHERE PurchaseInvoiceNo = @PurchaseInvoiceNo
    
  2. 遍历DataGridView中的每一行,执行INSERT语句把所有明细重新插入到表中
    INSERT INTO [dbo].[PurchaseInvoiceDetails] 
    (PurchaseInvoiceNo, ProductCode, ProductName, Box, Quantity, Price, DiscountInPercent, DiscountAmount, Amount)
    VALUES 
    (@PurchaseInvoiceNo, @ProductCode, @ProductName, @Box, @Quantity, @Price, @DiscountInPercent, @DiscountAmount, @Amount)
    
  3. 关键提醒:把更新主表PurchaseInvoice、删除旧明细、插入新明细的所有操作放在同一个数据库事务里,这样如果任何一步出错,所有操作都会回滚,避免出现主表更新了但明细表数据错乱的情况。

方案二:UPSERT(更新已有记录 + 插入新增记录)

如果需要保留原有明细记录(比如不想删除再插入),可以对每条明细判断是否存在,存在则更新,不存在则插入:

  1. 给PurchaseInvoiceDetails加一个唯一标识(比如新增主键PurchaseInvoiceDetailID,或者用PurchaseInvoiceNo + ProductCode作为唯一约束,假设一个订单里同一个产品只能出现一次)
  2. 对DataGridView的每一行:
    • 如果该明细已存在(比如通过PurchaseInvoiceNo和ProductCode能查到记录),执行你原来的UPDATE语句
    • 如果不存在,执行INSERT语句插入这条新明细
  3. 或者用SQL Server的MERGE语句一次性处理,示例如下(需要把DataGridView的数据整理成临时表或表变量作为源数据):
    MERGE INTO [dbo].[PurchaseInvoiceDetails] AS Target
    USING @TempDetailsTable AS Source
    ON Target.PurchaseInvoiceNo = Source.PurchaseInvoiceNo AND Target.ProductCode = Source.ProductCode
    WHEN MATCHED THEN
        UPDATE SET 
            Target.ProductName = Source.ProductName,
            Target.Box = Source.Box,
            Target.Quantity = Source.Quantity,
            Target.Price = Source.Price,
            Target.DiscountInPercent = Source.DiscountInPercent,
            Target.DiscountAmount = Source.DiscountAmount,
            Target.Amount = Source.Amount
    WHEN NOT MATCHED THEN
        INSERT (PurchaseInvoiceNo, ProductCode, ProductName, Box, Quantity, Price, DiscountInPercent, DiscountAmount, Amount)
        VALUES (Source.PurchaseInvoiceNo, Source.ProductCode, Source.ProductName, Source.Box, Source.Quantity, Source.Price, Source.DiscountInPercent, Source.DiscountAmount, Source.Amount);
    

额外注意事项

  • 始终使用参数化查询(你已经在做了,这点很棒,继续保持,能有效防止SQL注入)
  • 确保主表和明细表的操作在同一个事务中,保证数据一致性
  • 如果你的业务允许,优先用方案一,逻辑简单,不容易出现遗漏或判断错误的情况

内容的提问来源于stack exchange,提问作者Farooq Ahmed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:26:53