source net for data connectionstrings conexion cadena c# sql asp.net database sql-server-2008-r2

c# - for - data source vb net sql server



El valor devuelto usando String result=Command.ExecuteScalar() se produce un error cuando el resultado devuelve null (10)

El valor no es nulo, sino DBNull.Value.

object value = cmd.ExecuteScalar(); if(value == DBNull.Value)

Quiero recuperar el valor de la primera celda de la primera fila de la base de datos, funciona bien con el siguiente código. Pero cuando no se encuentra ningún resultado, arroja Excepción.

Cómo manejar con DBNull .
¿Debo cambiar mi consulta? ¿Qué valor devuelven si no hay registro de ellos?

System.NullReferenceException: referencia de objeto no establecida en una instancia de un objeto.

Código:

public string absentDayNo(DateTime sdate, DateTime edate, string idemp) { string result="0"; string myQuery="select COUNT(idemp_atd) absentDayNo from td_atd where "; myQuery +=" absentdate_atd between ''"+sdate+"'' and ''"+edate+" "; myQuery +=" and idemp_atd=''"+idemp+"'' group by idemp_atd "; SqlCommand cmd = new SqlCommand(myQuery, conn); conn.Open(); //System.NullReferenceException occurs when their is no data/result string getValue = cmd.ExecuteScalar().ToString(); if (getValue != null) { result = getValue.ToString(); } conn.Close(); return result; }


Esto debería funcionar:

var result = cmd.ExecuteScalar(); conn.Close(); return result != null ? result.ToString() : string.Empty;

Además, sugeriría usar Parámetros en su consulta, algo como (solo una sugerencia):

var cmd = new SqlCommand { Connection = conn, CommandType = CommandType.Text, CommandText = "select COUNT(idemp_atd) absentDayNo from td_atd where absentdate_atd between @sdate and @edate and idemp_atd=@idemp group by idemp_atd" }; cmd.Parameters.AddWithValue("@sdate", sdate); cmd.Parameters.AddWithValue("@edate", edate); // etc ...


No es necesario seguir llamando a .ToString() ya que getValue ya es una cadena.

Aparte de eso, esta línea podría ser tu problema:

string getValue = cmd.ExecuteScalar().ToString();

Si no hay filas .ExecuteScalar devolverá un null por lo que deberá realizar algunas comprobaciones.

Por ejemplo:

var firstColumn = cmd.ExecuteScalar(); if (firstColumn != null) { result = firstColumn.ToString(); }


Para trabajar con NpgsqlCommand o el estándar sqlCommand use:

int result = int.Parse(cmd.ExecuteScalar().ToString());


Prueba este

var getValue = cmd.ExecuteScalar(); conn.Close(); return (getValue == null) ? string.Empty : getValue.ToString();


Prueba este, si el valor 0 es nulo o algo

return command.ExecuteScalar() == DBNull.Value ? 0 : (double)command.ExecuteScalar();


Puedes usarlo como el siguiente

string result = null; object value = cmd.ExecuteScalar(); if (value != null) { result = value.ToString(); } conn.Close(); return result;


Si la primera celda devuelta es null , el resultado en .NET será DBNull.Value

Si no se devuelven celdas , el resultado en .NET será null ; no puede llamar a ToString() en un null . Por supuesto, puede capturar lo que devuelve ExecuteScalar y procesar los casos null / DBNull / otros por separado.

Dado que está agrupando, etc., probablemente podría tener más de un grupo. Francamente, no estoy seguro de que ExecuteScalar sea ​​tu mejor opción aquí ...

Adicional: el sql en la pregunta es malo de muchas maneras:

  • inyección SQL
  • internacionalización (esperemos que el cliente y el servidor estén de acuerdo en cómo se ve una fecha)
  • concatenación innecesaria en declaraciones separadas

Te sugiero fuertemente que parametrices; Tal vez con algo como "dapper" para hacerlo más fácil:

int count = conn.Query<int>( @"select COUNT(idemp_atd) absentDayNo from td_atd where absentdate_atd between @sdate and @edate and idemp_atd=@idemp group by idemp_atd", new {sdate, edate, idemp}).FirstOrDefault();

Todos los problemas resueltos, incluido el escenario "sin filas". Las fechas se pasan como fechas (no cadenas); El orificio de inyección se cierra mediante el uso de un parámetro. También obtienes reutilización del plan de consulta como un bono adicional. El group by aquí es redundante, por cierto. Si solo hay un grupo (a través de la condición de igualdad), puede seleccionar COUNT(1) .


Usar la función isnull del servidor SQL

public string absentDayNo(DateTime sdate, DateTime edate, string idemp) { string result="0"; string myQuery="select isnull(COUNT(idemp_atd),0) as absentDayNo from td_atd where "; myQuery +=" absentdate_atd between ''"+sdate+"'' and ''"+edate+" "; myQuery +=" and idemp_atd=''"+idemp+"'' group by idemp_atd "; SqlCommand cmd = new SqlCommand(myQuery, conn); conn.Open(); //System.NullReferenceException occurs when their is no data/result string getValue = cmd.ExecuteScalar().ToString(); if (getValue != null) { result = getValue.ToString(); } conn.Close(); return result; }


prueba esto :

string getValue = Convert.ToString(cmd.ExecuteScalar());