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

C#向存储过程用户定义数据表传递Null值的处理方案问询

解决SQL Server表值参数传递Null的问题

SQL Server的表值参数(TVP)不支持传递DBNull,必须传递结构匹配的DataTable——哪怕是空表,也不能传Null。你的问题出在当输入列表为Null时,直接尝试将其转成DataTable,最终传递了DBNull给存储过程参数。

处理方案

  • 替换Null列表为空列表:当finalinput.ProjectIds或finalinput.AccountIds为Null时,初始化一个空的对应类型列表,再转成DataTable,确保最终传递的是空的结构匹配的DataTable,而非DBNull。
  • 避免Null初始化List:直接用Null初始化List会抛出ArgumentNullException,必须先做Null判断,用空列表替代。

修改后的代码示例

public string SubmitGroupInfo(GroupSettingsInputs finalinput)
{
    string result = string.Empty;

    // 处理Null列表,替换为空列表
    List<ProjectIDinputList> ProjectIdDetails = finalinput.ProjectIds ?? new List<ProjectIDinputList>();
    List<AccountIDinputList> AccountIdDetails = finalinput.AccountIds ?? new List<AccountIDinputList>();

    DataTable projectlist = ToDataTable(ProjectIdDetails);
    DataTable accountlist = ToDataTable(AccountIdDetails);

    dbcmd = this.sqlConn.GetStoredProcCommand("SPName");
    dbcmd.CommandType = CommandType.StoredProcedure;
    dbcmd.CommandTimeout = 240;

    // 传递空DataTable而非DBNull,符合TVP要求
    this.sqlConn.AddParameter(dbcmd,"@ProjectIds",SqlDbType.Structured,projectlist);
    this.sqlConn.AddParameter(dbcmd,"@AccountIds",SqlDbType.Structured,accountlist);

    using (IDataReader datareader = this.sqlConn.ExecuteReader(dbcmd))
    {
        while (datareader.Read())
        {
            result = Convert.ToString(datareader["result"]);
        }
    }

    return result;
}

额外说明

如果存储过程逻辑需要区分“传递了空列表”和“未传递参数”,可以在存储过程里判断TVP的行数:比如用IF EXISTS(SELECT 1 FROM @ProjectIds)来处理有数据的情况,否则走AccountId的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 00:35:31