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());