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

.NET中如何结合GO语句使用参数化查询?

解决方案:无需GO语句,用参数化批量插入优化并发与锁

首先明确:GO不是必须的,它只是SQL Server客户端工具(比如SSMS)用来拆分脚本的批处理分隔符,并非T-SQL原生语法,数据库引擎本身不识别GO。你的核心需求是优化并发、减少锁表中断,应该从批量插入的效率和事务管理入手,而非依赖GO。

为什么GO帮不了你

GO会把脚本拆分成多个独立批处理,每个批处理单独执行,反而会增加数据库往返次数,每个批处理的锁都要单独申请释放,间隙期更容易被其他进程抢占锁,反而可能加剧锁冲突,完全达不到你想要的效果。

用SqlCommand实现高效参数化批量插入的两种方案

方案1:表值参数(推荐,适合大量行插入)

这是SQL Server最高效的批量参数化插入方式,只需一次数据库往返,锁持有时间最短,同时完全避免SQL注入。

第一步:在SQL Server创建表类型

CREATE TYPE [dbo].[TableType_Insert] AS TABLE(
    [id] INT,          -- 匹配你的表字段类型
    [type] INT,
    [value] VARCHAR(100) -- 替换为实际字段类型
)

第二步:C#代码实现

// 构造要插入的数据表
DataTable insertData = new DataTable();
insertData.Columns.Add("id", typeof(int));
insertData.Columns.Add("type", typeof(int));
insertData.Columns.Add("value", typeof(string));

// 添加需要插入的行
insertData.Rows.Add(id, 10, value1);
insertData.Rows.Add(id, 15, value2);
insertData.Rows.Add(id, 20, value3);
// 可继续添加更多行...

using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["context"].ConnectionString))
{
    string query = @"
        INSERT INTO [dbo].[table_name] (id, type, value)
        SELECT id, type, value FROM @InsertData
    ";

    SqlCommand sqlCommand = new SqlCommand(query, connection);
    // 配置表值参数
    SqlParameter tvpParam = sqlCommand.Parameters.AddWithValue("@InsertData", insertData);
    tvpParam.SqlDbType = SqlDbType.Structured;
    tvpParam.TypeName = "[dbo].[TableType_Insert]"; // 指定刚才创建的表类型

    connection.Open();
    sqlCommand.ExecuteNonQuery();
}

方案2:多行VALUES语法(适合少量行插入)

把多个INSERT合并为单个INSERT语句,用多行VALUES语法,同样是单次批处理执行,参数化简单。

string query = @"
    INSERT INTO [dbo].[table_name] (id, type, value)
    VALUES 
        (@id, 10, @value1),
        (@id, 15, @value2),
        (@id, 20, @value3)
        -- 可继续添加更多行...
";

using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["context"].ConnectionString))
{
    SqlCommand sqlCommand = new SqlCommand(query, connection);
    sqlCommand.Parameters.AddWithValue("@id", id);
    sqlCommand.Parameters.AddWithValue("@value1", value1);
    sqlCommand.Parameters.AddWithValue("@value2", value2);
    sqlCommand.Parameters.AddWithValue("@value3", value3);
    // 对应添加更多参数...

    connection.Open();
    sqlCommand.ExecuteNonQuery();
}

额外优化:事务管理

如果需要保证所有插入要么全部成功要么全部失败,可以把执行逻辑包裹在显式事务中,减少锁的持有时间(相比自动提交每个INSERT):

using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["context"].ConnectionString))
{
    connection.Open();
    using (SqlTransaction transaction = connection.BeginTransaction())
    {
        try
        {
            // 这里放入上述任意一种方案的SqlCommand执行逻辑
            sqlCommand.Transaction = transaction;
            sqlCommand.ExecuteNonQuery();

            transaction.Commit();
        }
        catch (Exception)
        {
            transaction.Rollback();
            throw;
        }
    }
}

内容的提问来源于stack exchange,提问作者Seth R.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 14:06:27