none
Error System.InvalidCastException: 'No se puede convertir un objeto DBNull en otros tipos.' RRS feed

  • Pregunta

  • Saludos amigos

    Estoy realizando una aplicacion en webforms c#, Usando SQLSERVEr

    Estoy sumando unos registros en la base de datos y cuando no encuentra ese datos me devuelve un NULL y en la aplicacion me da un error que es el siguiente: 

    System.InvalidCastException: 'No se puede convertir un objeto DBNull en otros tipos.'

    Mi codigo en c# es el siguiente:

    SqlConnection con2 = new SqlConnection(ConfigurationManager.ConnectionStrings["connectionString"].ToString());
                        con2.Open();

                        SqlParameter param13 = new SqlParameter("@Cov_Fecha", DateTime.Now.Date);
                        SqlParameter param14 = new SqlParameter("@Cov_Transaccion", "Compra");
                        SqlParameter param15 = new SqlParameter("@Cov_MonedaP", DdlMoneda.Text);
                        SqlCommand cmd10 = new SqlCommand("sp_Control_Divisa", con2);
                        cmd10.Parameters.Add(param13);
                        cmd10.Parameters.Add(param14);
                        cmd10.Parameters.Add(param15);
                        cmd10.CommandType = CommandType.StoredProcedure;
                        decimal SumaMonto = Convert.ToDecimal(cmd10.ExecuteScalar());
                        Label1.Text = SumaMonto.ToString("N2");

    El error me lo envia en la suiente linea:

    decimal SumaMonto = Convert.ToDecimal(cmd10.ExecuteScalar());

    El codigo del storeprodure es el siguiente:

    USE [Divisas]
    GO
    /****** Object:  StoredProcedure [dbo].[sp_Control_Divisa]    Script Date: 3/5/2020 7:01:50 a.m. ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER proc [dbo].[sp_Control_Divisa]

    @Cov_Fecha date = '',
    @Cov_Transaccion varchar(7) = '',
    @Cov_MonedaP varchar(50) = ''

    as
    begin
    Select SUM(Cov_Monto) from [CompraVenta] where Cov_Fecha=@Cov_Fecha and Cov_Transaccion=@Cov_Transaccion and Cov_MonedaP=@Cov_MonedaP
    end 

    La tabla es la suiente:

    Cov_Factura    int                   Unchecked
    Cov_Fecha            date                Checked
    Cov_Hora            time(0)           Checked
    Cov_Caja            varchar(50)      Checked
    Cov_Cajero          varchar(30)       Checked
    Cov_Cliente    varchar(12)    Checked
    Cov_CedulaRNC   varchar(13)    Checked
    Cov_Nombre        varchar(50)    Checked
    Cov_Transaccion   varchar(7)    Checked
    Cov_MonedaP   varchar(50)        Checked
    Cov_Canje           decimal(18, 2)    Checked
    Cov_CantidadP     decimal(18, 2)    Checked
    Cov_MonedaC      varchar(50)     Checked
    Cov_PrecioC   decimal(18, 2)     Checked
    Cov_CantidadM   decimal(18, 2)     Checked
    Cov_MonedaV   varchar(50)     Checked
    Cov_PrecioV   decimal(18, 2)     Checked
    Cov_Monto   decimal(18, 2)     Checked
    Cov_Comentario   varchar(50)     Checked

    Amigos por favor como puedo resolver este problema podrian ayudarme a completar el codigo que me falta para resolverlo.

    Gracias

    domingo, 3 de mayo de 2020 12:26

Respuestas

  • El mensaje de error indica que al llamar a ExecuteScalar éste ha devuelto un NULL desde la base de datos, que en el lado cliente se convierte en un objeto DBNull, y este DBNull no se puede convertir en Decimal.

    ¿Y por qué puede devolver NULL el procedimiento, si es un "Select SUM(...)"? Pues cuando no hay ningún registro que cumpla la condición que hay en el Where. Podrías pensar que en ese caso la suma sería cero, pero no, cuando no hay ningún registro para sumar la suma devuelve NULL en lugar de cero.

    ¿Cómo se soluciona? Pues una de dos: o cambias el procedimiento para que no devuelva NULL, o cambias el código cliente metiendo un "if" que compare con DBNull y no intente convertirlo a Decimal si eso sucede.

    En el procedimiento, así:

    Select COALESCE(SUM(Cov_Monto),0) from ...

    En el cliente, por ejemplo así:

    decimal SumaMonto = 0;

    object valorDevuelto = cmd10.ExecuteScalar();

    if (!(valorDevuelto is DBNull)) then SumaMonto = Convert.ToDecimal(valorDevuelto);


    domingo, 3 de mayo de 2020 12:50

Todas las respuestas

  • El mensaje de error indica que al llamar a ExecuteScalar éste ha devuelto un NULL desde la base de datos, que en el lado cliente se convierte en un objeto DBNull, y este DBNull no se puede convertir en Decimal.

    ¿Y por qué puede devolver NULL el procedimiento, si es un "Select SUM(...)"? Pues cuando no hay ningún registro que cumpla la condición que hay en el Where. Podrías pensar que en ese caso la suma sería cero, pero no, cuando no hay ningún registro para sumar la suma devuelve NULL en lugar de cero.

    ¿Cómo se soluciona? Pues una de dos: o cambias el procedimiento para que no devuelva NULL, o cambias el código cliente metiendo un "if" que compare con DBNull y no intente convertirlo a Decimal si eso sucede.

    En el procedimiento, así:

    Select COALESCE(SUM(Cov_Monto),0) from ...

    En el cliente, por ejemplo así:

    decimal SumaMonto = 0;

    object valorDevuelto = cmd10.ExecuteScalar();

    if (!(valorDevuelto is DBNull)) then SumaMonto = Convert.ToDecimal(valorDevuelto);


    domingo, 3 de mayo de 2020 12:50
  • Gracias Alberto 

    funciono muy bien

    Gracias

    Dejare el codigo del procedimiento para si alguien algun dia lo necesite:

    USE [Divisas]
    GO
    /****** Object:  StoredProcedure [dbo].[sp_Control_Divisa]    Script Date: 3/5/2020 7:01:50 a.m. ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER proc [dbo].[sp_Control_Divisa]

    @Cov_Fecha date = '',
    @Cov_Transaccion varchar(7) = '',
    @Cov_MonedaP varchar(50) = ''

    as
    begin
    Select COALESCE(SUM(Cov_Monto),0) from [CompraVenta] where Cov_Fecha=@Cov_Fecha and Cov_Transaccion=@Cov_Transaccion and Cov_MonedaP=@Cov_MonedaP
    end 

    domingo, 3 de mayo de 2020 12:57
  • Hola

     

     

    Gracias por levantar tu consulta en los foros de MSDN. Cerraremos el Hilo, por ende si tiene alguna otra consulta por favor genera otra consulta para que la comunidad de foros te pueda asesorar.

     

    Siempre es un placer atender tus consultas!

     

    Gracias por usar los foros de MSDN.

     

    Oscar Navarro

    martes, 5 de mayo de 2020 16:21
    Moderador