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

C# 基于JSON数组动态翻转SQL Server SelectedType表bit字段值的实现方法

问题解答

1. 翻转bit类型值的SQL逻辑

SQL Server中翻转bit字段有两种常用的稳定写法,二选一即可:

  • 写法1:用按位取反符~直接取反
    UPDATE SelectedType SET [列名] = ~[列名] WHERE P_ID = @id
    
  • 写法2:用算术运算实现翻转,可读性更高
    UPDATE SelectedType SET [列名] = 1 - [列名] WHERE P_ID = @id
    

注意:动态拼接列名时最好加上方括号[],避免列名和SQL关键字冲突引发报错

2. 原有代码的问题修正

你现有代码存在几个明显错误,需要同步调整:

  • 事务提交、连接关闭操作不能放在for循环内部,否则第一次循环执行完就会提交事务、关闭连接,后续循环直接报错,需要挪到整个for循环执行结束后
  • 直接拼接列名存在SQL注入风险,需要先对传入的列名字符串做合法性校验,比如限制只能包含字母、数字、下划线,且前缀为type_
  • 你给出的表示例中主键是P_ID不是id,WHERE条件要对应修改
  • 原SQL中额外加的AND 列名 = @列名条件完全冗余,也不需要给对应列传参

3. 修正后的完整代码

public bool UpdatePredictSubGoalType(int id, string _selectedTypes)
{
    string a = "[]";
    string item = _selectedTypes;

    if (!item.Contains('[') && !item.Contains(']'))
    {
        string c = a.Insert(1, _selectedTypes);
        item = c;
    }

    bool res = false;
    JArray Ja = JArray.Parse(item);
    // 合法列名正则校验规则,避免SQL注入
    var validColRegex = new System.Text.RegularExpressions.Regex(@"^type_[0-9_]+$");
    SqlTransaction trans = null;
    SqlConnection conn = null;

    try
    {
        using (conn = new SqlConnection(CommonDA.GetConnectionString()))
        {
            conn.Open();
            trans = conn.BeginTransaction();
            try
            {
                for (int i = 0; i < Ja.Count; i++)
                {
                    string x = Ja[i]["value"]?.ToString()?.Trim();
                    // 校验列名合法性,非法值直接跳过
                    if (string.IsNullOrEmpty(x) || !validColRegex.IsMatch(x))
                        continue;
                    
                    SqlCommand cmd = conn.CreateCommand();
                    // 核心翻转逻辑,这里用1-字段的写法,也可以换成~[x]
                    string sqlstr = $@"UPDATE SelectedType SET [{x}] = 1 - [{x}] WHERE P_ID = @id";
                    cmd.CommandText = sqlstr;
                    cmd.Transaction = trans;
                    cmd.Parameters.AddWithValue("@id", id);                            
                    cmd.ExecuteNonQuery();
                }
                // 所有列更新完成后再提交事务
                trans.Commit();
                res = true;
            }
            catch (Exception Err)
            {
                trans.Rollback();
                CommonLB.SystemError(Err.Message);
                CommonLB.SystemError("Data", "SQL执行出错");
            }
            finally
            {
                conn?.Close();
            }
        }
    }
    catch (Exception Err)
    {
        throw new ApplicationException(Err.Message, Err);
    }

    return res;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 10:09:00