【问题标题】:Best method of assigning NULL value to SqlParameter将 NULL 值分配给 SqlParameter 的最佳方法
【发布时间】:2012-12-20 22:04:32
【问题描述】:

我在 C# 类方法中使用了许多可选输入参数。由于在不使用参数时可选语法会创建一个值“0”,因此我在该方法中调用的 SQL 插入命令最终会以这种方式插入。但是,当不使用参数时,我需要该命令插入 NULL 值而不是 0。在不使用大量“if”语句的情况下完成此任务的最佳方法是什么?

下面是我所指的代码。是否有某种语法/命令允许我在 SqlParameter 声明中指定 NULL 值?

public int batchInsert
(
    int id, 
    int outcome, 
    int input = 0, 
    int add = 0, 
    int update = 0,
    int delete = 0,
    int errors = 0, 
    int warnings = 0
)
{
    string sts;
    if (outcome == 0)
    {
        sts = "S";
    }
    else if (outcome == 1)
    {
        sts = "W";
    }
    else
    {
        sts = "E";
    }

    SqlConnection sqlConn = new SqlConnection(this.connString);
    SqlParameter runId = new SqlParameter("@runId", id);
    SqlParameter endTime = new SqlParameter("@endTime", DateTime.Now);
    SqlParameter status = new SqlParameter("@status", sts);
    SqlParameter sqlInput = new SqlParameter("@itemsRead", input);
    SqlParameter sqlAdd = new SqlParameter("@add", add);
    SqlParameter sqlUpdate = new SqlParameter("@update", update);
    SqlParameter sqlDelete = new SqlParameter("@delete", delete);
    SqlParameter sqlError = new SqlParameter("@errors", errors);
    SqlParameter sqlWarning = new SqlParameter("@warnings", warnings);
    SqlParameter result = new SqlParameter("@outcome", results[outcome]);
    SqlCommand sqlComm = new SqlCommand(insertCommand(), sqlConn);

【问题讨论】:

  • 您是否遇到过零是要写入数据库表的合法值的情况?
  • 如果您在 C# 中使用可为空的类型,您可以使用此语法将数据库 NULL 替换为 C# nullmyVariable ?? (object)DBNull.Value

标签: c# null sqlparameter


【解决方案1】:

是的,对于参数的值,只需使用DBNull.Value。例如:

SqlParameter sqlError = 
    new SqlParameter("@errors", errors == 0 ? (object)DBNull.Value : errors);

或者写一个小助手:

private object ValueOrDBNullIfZero(int val) {
   if ( val == 0 ) return DBNull.Value;
   return val;
}

然后:

SqlParameter sqlError = 
    new SqlParameter("@errors", ValueOrDBNullIfZero(errors));

【讨论】:

  • 出于某种原因,我只看到“是的,对于参数的值,只需使用 DbNull.Value”,而不是示例。谢谢!
  • @georgem - 是的,我认为这应该也可以,尽管大多数时候 ADO.NET 足够聪明,可以自行将 null 值转换为 DbNull.Value,所以我不确定这是否有必要。
  • 谢谢,完美满足我的需求。不要忘记在表格列上允许空值。
  • 谢谢。正是我正在处理的一段代码所需要的。
【解决方案2】:

您需要检查每个参数值并使用DBNull.Value 发送空值。我们有一个关闭object 的扩展方法来简化此操作。

public static class ObjectExtensions
{
    public static object OptionalParam<T>(this T value, T optionalValue = default(T))
    {
        return Equals(value,optionalValue) ? (object)DBNull.Value : value;
    }
}

用法:

var sqlInput = new SqlParameter("@itemsRead", input.OptionalParam());

或者如果你想考虑一个非默认的任意值作为默认值:

var sqlInput = new SqlParameter("@itemsRead", input.OptionalParam(-1));

【讨论】:

    【解决方案3】:

    这是将 Null 值分配给 sql 参数的最简单方法

                command.Parameters.AddWithValue("@Comment", string.IsNullOrEmpty(comment) ? (object)DBNull.Value : comment);   
    

    【讨论】:

    • 另一种选择是使用Convert.DBNull 而不是(object)DBNull.Value。示例(带有可为空的 int):command.Parameters.AddWithValue("@optionalParam", id.HasValue ? id.Value : Convert.DBNull);
    【解决方案4】:

    考虑使用可用的Nullable(T) 结构。它只会让你设置值,如果你有它们,你的 SQL Command 对象将识别可以为空的值并相应地处理,而你不会有任何麻烦。

    【讨论】:

      【解决方案5】:

      使用小的帮助类我们可以创建扩展方法来添加 DBNull.Value 到 sqlparameter

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Web;
      using System.Data.SqlClient;
      using System.Data;
      using System.Data.Common;
      
      namespace System.Data.SqlClient
      {
          public static class ExtensionMethods 
      
          {
      
      
      
              public static SqlParameter AddParameter(this SqlParameterCollection parms, SqlParameter param)
              {
                  if (param.Value == null)
                  {
                      param.Value = DBNull.Value;
                      return parms.Add(param);
                  }
                  else
                  {
                      return parms.Add(param);        
                  }
      
              }
      }
      

      用法

      SqlParameter _FraudPackageID = new SqlParameter("@FraudPackageID", System.Data.SqlDbType.BigInt);
       _FraudPackageID.Value = FraudPackageID;
       _FraudPackageID.Direction = System.Data.ParameterDirection.Input;
      
      _cmd.Parameters.AddParameter(_FraudPackageID);
      

      如果您将 null 作为值分配或传递给 sqlparameter,此扩展方法将自动将其转换为 DBNull 并重新分配给 sqlparameter。

      所以无需担心我们动态传递的值是什么。

      【讨论】:

        【解决方案6】:

        语法短!

          cmd.Parameters.Add(new SqlParameter{SqlValue=username ?? (object)DBNull.Value,ParameterName="usuario" }  );
        

        【讨论】:

          【解决方案7】:

          另一种在必要时设置空日期时间参数的清晰方法

          if(obj.myDate == DateTime.MinValue)
          {
              aCommand.Parameters.Add("dateParameter", SqlDbType.Date).Value = DBNull.Value;
          }
          else
          {
              aCommand.Parameters.Add("dateParameter", SqlDbType.Date).Value = obj.myDate ;
          }
          

          【讨论】:

            猜你喜欢
            • 2011-06-01
            • 1970-01-01
            • 2020-06-21
            • 1970-01-01
            • 1970-01-01
            • 2014-04-30
            • 1970-01-01
            • 2014-03-29
            相关资源
            最近更新 更多