【问题标题】:Using DBNull.Value with SqlParameter without knowing sqlDbType?在不知道 sqlDbType 的情况下将 DBNull.Value 与 SqlParameter 一起使用?
【发布时间】:2011-05-12 11:46:25
【问题描述】:

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

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

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

本质上是把DBNull传给数据库,不指定类型,让数据库处理?

【问题讨论】:

  • 您应该真正了解应用程序中的列类型。

标签: c# .net sql sql-server


【解决方案1】:

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

【讨论】:

    【解决方案2】:
    command.Parameters.AddWithValue("@param", DBNull.Value);
    

    【讨论】:

      【解决方案3】:

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

      Convert.DBNull
      

      像这样

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

      【讨论】:

      • 这是事先不知道类型的问题的通用解决方案!
      • 不幸的是,我无法让它适用于 varbinary 类型。
      【解决方案4】:

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

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

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

      Source

      【讨论】:

        【解决方案5】:

        我正在处理一种内部 ORM,它使用 objects 生成参数。由于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));
        }
        

        【讨论】:

          猜你喜欢
          • 2017-11-27
          • 1970-01-01
          • 1970-01-01
          • 2016-05-18
          • 1970-01-01
          • 2020-06-01
          • 2013-08-19
          • 1970-01-01
          • 2012-05-04
          相关资源
          最近更新 更多