在不知道sqlDbType的情况下将DBNull.Value与SqlParameter一起使用?

时间:2010-11-19 06:58:06

标签: c# .net sql sql-server

我正在使用SqlParameter将空值传递给可以为空的各种列的表。问题是如果没有sqlDbType,SqlParameter看起来默认为nvarchar。如果实际的db类型是varbinary,则会出现问题。我得到一个例外

  

不允许从数据类型nvarchar到varbinary(max)的隐式转换。使用CONVERT函数运行此查询。

当我创建SqlParameter时,我所知道的只是参数的名称和对象。如果对象为null,SqlParameter显然无法推断出要使用的正确类型,那么有没有办法将SqlParameter与null值一起使用,而不必在创建sql参数时知道sqlDbType?

基本上将DBNull传递给数据库而不指定类型,让数据库处理它吗?

5 个答案:

答案 0 :(得分:4)

旧帖但可能对其他人有帮助。

Convert.DBNull

喜欢这个

command.Parameters.AddWithValue("@param", Convert.DBNull);

答案 1 :(得分:1)

设置NULL列的默认值(为NULL),然后不要在insert语句中传递任何NULL列。

答案 2 :(得分:0)

  

还有另一种方法可以做到这一点。你仍然可以使用AddWithValue,   但是使用SqlBinary.Null而不是DBNull.Value:

     

c.Parameters.AddWithValue(“@ cfp”,SqlBinary.Null);

     

不要忘记将System.Data.SqlTypes导入到项目中。

Source

答案 3 :(得分:0)

我正在处理一种使用objects生成参数的内部ORM。由于它们在null时基本上没有类型,因此很难区分各种SQL空类型。

DBNull.Value适用于几乎所有SQL类型,但对于我使用的varbinary(max)列,它失败了。相反,你必须使用SqlBinary.Null - 不要问我为什么。

我决定在这里使用一个特殊的标记值来指示何时应该使用此列类型。除了我们的" ORM"下面:

using System.Data.SqlTypes;

class MyModelType
{
    public Guid ID { get; set; }
    public byte[] Data { get; set; }
}

static readonly object NullSqlBinary = new object();

object SqlValueForObject(object val)
{
    if (val == null)
    {
        val = DBNull.Value;
    }
    else if (val == NullSqlBinary)
    {
        val = SqlBinary.Null;
    }
    return val;
}

IDictionary<string, object> Params(MyModelType x)
{
    return new Dictionary<string, object>
    {
        { "@ID", x.ID },
        { "@Data", x.Data ?? NullSqlBinary },
    };
}

private SqlCommand CreateCommand()
{
    var cmd = Connection.CreateCommand();
    cmd.CommandTimeout = 60;

    return cmd;
}

SqlCommand CreateCommand(string sql, IDictionary<string, object> values)
{
    var cmd = CreateCommand();
    cmd.CommandText = sql;
    cmd.Transaction = GetCurrentTransaction();

    cmd.Parameters.Clear();
    if (values != null)
    {
        foreach (var kvp in values)
        {
            object sqlVal = SqlValueForObject(kvp.Value);
            cmd.Parameters.AddWithValue(kvp.Key, sqlVal);
        }
    }
    return cmd;
}

int Execute(string sql, IDictionary<string, object> values)
{
    using (var cmd = CreateCommand(sql, values))
    {
        return cmd.ExecuteNonQuery();
    }
}

void InsertMyModel(MyModelType obj)
{
    DB.Execute(
        @"INSERT INTO MyTable (ID, Data)
        VALUES (@ID, @Data)", Params(obj));
}

答案 4 :(得分:-1)

command.Parameters.AddWithValue("@param", DBNull.Value);