viernes, 18 de junio de 2010

Problema con los nulos en campos image de SQL con ASP.NET

Voy a explicar primero en que escenario me estoy moviendo y los pasos que he dado para solucionar los problemas para almacenar un valor nulo en un campo del tipo image en una base de datos SQL.

En la base de datos SQL tengo una tabla con un campo del tipo image que admite nulos.
En esta misma base de datos creo un procedimiento almacenado para insertar y actualizar la tabla

Desde .NET creo un Data Set con tipo donde creo un DataTable con los campos de la tabla de SQL y le asigno a cada campo su tipo de datos. En el caso del campo Imagen le asigno el tipo de datos de .Net System.byte(). Utilizo este DataTable para cargar la información de campos de varias tablas de la base de datos SQL.

A la hora de llamar al procedimiento almacenado desde .NET le indico los parámetros en un objeto sqlCommand y lo ejecuto como ExecuteNonQuery.


A primera vista todos los pasos funcionan correctamente y no tengo ningún error de compilación.

Primer error que me sucede al intentar guardar un valor nulo en el campo imagen


Por el punto donde da el error es en la clase que genera automáticamente a partir del DataSet. Esta dando en la columna imagen en el DataTable que he creado. Se produce porque al crear el campo Imagen he dejado indicado en las propiedades que genere una excepción si se encuentra con nulos.

Veo dos opciones para evitar este error

  • La primera es modificar la propiedad NullValue del campo Image para que en vez de generar una excepción cuando contienen nulos, que no haga nada (es una opción del desplegable de ese campo)

  • La segunda es modificar el código donde añado el parámetro @Imagen. En vez de utilizar un IIF abreviado donde se evalúan las dos partes (y ahí salta el error), utilizar un If por separado, de tal manera que si la imagen es nulo, no se llegue a evaluar.
Parece que todo va bien, pero cuando volvemos a ejecutar nos encontramos con otro error.
En este caso se genera el error cuando se ejecuta el command del procedimiento almacenado. Lo primero que llama la atención es que en el error habla del tipo de datos nvarchar, que no hemos utilizado en ningún momento.
Si ponemos un punto de ruptura y miramos el parámetro imagen que enviamos al procedimiento almacenado nos encontramos con la sorpresa que el tipo de datos que estamos enviando es un nVarchar (propiedad sqlDbType).

Esto pasa porque al añadir el parámetro al command no le indicamos ningún tipo de datos, sino que solo pasamos el nombre del parámetro y el valor

La solución viene por indicar en el parámetro del command que el tipo de datos sql es un Image

Por lo que si volvemos a repetir la ejecución podemos comprobar en la inspección del parámetro @imagen del command que ha desaparecido el tipo nvarchar por el image y funciona todo correctamente