You need to enable JavaScript to run this app. C# 基于编辑后DataGridView数据更新SQL表的最优实践咨询
优惠活动
大模型
产品
解决方案
定价
更多

C# 基于编辑后DataGridView数据更新SQL表的最优实践咨询

C#小批量数据表更新最优实践及实现方案

方案选型建议

优先选择参数化批量更新方案,绝对不推荐先删除再插入的做法,原因如下:

  • 删除再插入会产生大量不必要的数据库日志,性能远低于直接更新
  • 若表存在外键约束,删除操作会直接触发约束报错,流程无法执行
  • 自增主键、行版本戳、数据库默认值字段会在重插时被覆盖,破坏原有数据一致性
  • 事务容错性极低,若删除后插入环节出错,会直接导致对应行数据丢失

现有代码问题修复

你当前的代码存在2个明显问题:

  1. 字符串拼接SQL存在SQL注入风险
  2. 数据库连接未做资源释放,可能引发连接泄漏
    修复后的代码如下:
public DataTable GetSingleTable(string sTableName, string sGetConnString, string sBranchID)  
{  
    DataTable dtTabletoReturn = new DataTable();
    // 用参数化查询避免SQL注入
    string sCommand = $"SELECT * FROM {sTableName} WHERE BranchID = @BranchID";
    // using会自动释放连接资源,不需要手动Close
    using (SqlConnection sqlConnection = new SqlConnection(sGetConnString))
    {
        SqlDataAdapter sqlOilAdapter = new SqlDataAdapter(sCommand, sqlConnection);
        // 添加参数
        sqlOilAdapter.SelectCommand.Parameters.AddWithValue("@BranchID", sBranchID);
        sqlOilAdapter.Fill(dtTabletoReturn);
    }
    return dtTabletoReturn;  
}

具体实现方案

方案1:SqlDataAdapter自动更新(最简单,适合100条级别的小表)

直接利用SqlCommandBuilder自动生成增删改命令,不需要手动写SQL,代码量极小:

public void SaveTableChanges(DataTable dtModified, string sTableName, string sGetConnString, string sBranchID)
{
    string sCommand = $"SELECT * FROM {sTableName} WHERE BranchID = @BranchID";
    using (SqlConnection sqlConnection = new SqlConnection(sGetConnString))
    {
        SqlDataAdapter sqlOilAdapter = new SqlDataAdapter(sCommand, sqlConnection);
        sqlOilAdapter.SelectCommand.Parameters.AddWithValue("@BranchID", sBranchID);
        // 自动生成对应的INSERT/UPDATE/DELETE命令
        SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(sqlOilAdapter);
        // 直接提交DataTable的修改到数据库
        sqlOilAdapter.Update(dtModified);
    }
}

注意:使用该方案需要保证查询的表设置了主键,否则SqlCommandBuilder无法自动生成更新条件。
这个方案会自动识别DataTable里新增、修改、删除的行,分别执行对应的SQL,完全匹配你的需求。

方案2:表值参数+UPDATE FROM(高性能,可扩展到万行级数据)

如果你想要自己实现类似SQL中UPDATE FROM的批量更新逻辑,可以用SQL Server的表值参数(TVP)实现:

  1. 首先在SQL Server中创建对应的表值类型:
CREATE TYPE YourTableType AS TABLE 
(
    -- 字段和你要更新的表结构、主键保持一致
    ID INT PRIMARY KEY,
    Column1 NVARCHAR(50),
    Column2 INT,
    BranchID VARCHAR(50)
)
  1. C#端代码实现:
public void BatchUpdateTable(DataTable dtModified, string sGetConnString)
{
    using (SqlConnection conn = new SqlConnection(sGetConnString))
    {
        conn.Open();
        string updateSql = @"
            UPDATE t
            SET t.Column1 = tvp.Column1, t.Column2 = tvp.Column2
            FROM 你的目标表 t
            INNER JOIN @ChangeTable tvp ON t.ID = tvp.ID
            WHERE t.BranchID = tvp.BranchID
        ";
        using (SqlCommand cmd = new SqlCommand(updateSql, conn))
        {
            // 传入表值参数
            SqlParameter param = cmd.Parameters.AddWithValue("@ChangeTable", dtModified);
            param.SqlDbType = SqlDbType.Structured;
            param.TypeName = "YourTableType"; // 和你SQL里建的表值类型名一致
            
            cmd.ExecuteNonQuery();
        }
    }
}

这个方案就是你要的C#端实现UPDATE FROM批量更新的方式,性能比单条UPDATE高很多,就算后续数据量涨到几千上万条也能hold住。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 04:45:03