2010-11-19 30 views
5

Estoy usando un SqlParameter para pasar valores nulos a una tabla para varias columnas que pueden contener nulos. El problema es que SqlParameter parece tener como valor predeterminado nvarchar si no está presente sqlDbType. Esto presenta un problema si el tipo de db real es varbinary; Obtengo una excepción que dice¿Usando DBNull.Value con SqlParameter sin conocer sqlDbType?

La conversión implícita del tipo de datos nvarchar a varbinary (max) no está permitida. Use la función CONVERTIR para ejecutar esta consulta.

Cuando creo el SqlParameter, todo lo que sé es el nombre del parámetro y el objeto. Si el objeto es nulo, SqlParameter obviamente no puede inferir el tipo correcto para usar, entonces ¿hay alguna manera de usar SqlParameter con valores nulos, sin tener que conocer el sqlDbType al crear el parámetro sql?

¿Pasa esencialmente el DBNull a la base de datos sin especificar el tipo y deja que la base de datos lo maneje?

+0

Realmente debe saber cuáles son los tipos de columna en su aplicación. – cjk

Respuesta

1

Establezca el valor predeterminado de las columnas NULL (a NULO) y luego no pase ninguna columna NULL en su instrucción de inserción.

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

Publicación anterior pero podría ser útil para otra persona.

Convert.DBNull 

gusta esta

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

** ¡Esta es la solución genérica para el problema sin conocer el tipo antes mencionado! ** – CodeAngry

+0

Desafortunadamente, no puedo hacer que esto funcione para los tipos 'varbinary'. – jocull

0

Hay otra manera de hacer esto. Puede seguir utilizando AddWithValue, sin embargo utilizar SqlBinary.Null en lugar de DBNull.Value:

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

No olvides importar System.Data.SqlTypes en tu proyecto.

Source

0

estoy tratando con una especie de ORM en el local que utiliza objects para generar parámetros. Dado que son esencialmente sin tipo cuando null hace que sea difícil diferenciar los distintos tipos de SQL null.

DBNull.Value funciona para casi todos los tipos de SQL, pero falla para una columna varbinary(max) que estoy usando. En su lugar, debe usar SqlBinary.Null - no me pregunte por qué.

Decidí usar un valor etiquetado especial aquí para indicar cuándo se debe usar este tipo de columna. Completo, excepto desde nuestro "ORM" a continuación:

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)); 
} 
Cuestiones relacionadas