2013-05-20 11 views
20

Desidero recuperare il valore 1a riga della prima cella dal database funziona correttamente con il codice riportato di seguito. Ma quando non viene trovato alcun risultato, genera Eccezione.Valore restituito utilizzando String risultato = errore Command.ExecuteScalar() si verifica quando il risultato restituisce null

Come gestire con DBNull.
Devo modificare la mia ricerca? che restituiscono un valore se non c'è nessun record?

System.NullReferenceException: riferimento oggetto non impostato su un'istanza di un oggetto.

Codice:

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; 
    } 
+1

Dove lancia un'eccezione ?? –

+1

L'eccezione genera 'string getValue = cmd.ExecuteScalar(). ToString();' l'errore medio si verifica quando il loro non è risultato –

+4

btw, che è un ** ** ** ** pessimo modo di costruire una query; foro di iniezione sql chiaro e evidente; c'è anche un problema di internazionalizzazione e alcune stringhe intermedie non necessarie. Spero che non sia come lo fai sql normalmente ... –

risposta

44

Non v'è alcuna necessità di continuare ad invocare .ToString() come getValue è già una stringa.

A parte che, questa linea potrebbe essere il problema:

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

Se non ci sono file .ExecuteScalar tornerà null quindi è necessario fare qualche controllo.

Per esempio:

var firstColumn = cmd.ExecuteScalar(); 

if (firstColumn != null) { 
    result = firstColumn.ToString(); 
} 
+0

grazie a questo funziona bene, anche la risposta di Naresh Parmar ha funzionato per mio aggiungendo il controllo per la stringa è "" –

+1

o potresti usare 'Convert.ToString (cmd.ExecuteScalar());' - questo ti darà 'String.Empty' se il valore è 'null'. – DrNachtschatten

5

È possibile utilizzare il seguente

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

@Satindersingh dove hai provato? che codice hai usato? il codice nella domanda non mostra questo ... –

+0

Sì, dovrebbe funzionare. –

+0

sì, funziona anche, scusa per prev cmnt –

2

provare questo:

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

questo dovrebbe funzionare:

var result = cmd.ExecuteScalar(); 
conn.Close(); 

return result != null ? result.ToString() : string.Empty; 

Inoltre, suggerirei usando i parametri nella query, qualcosa di simile (solo un suggerimento):

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 [email protected] group by idemp_atd" 
}; 

cmd.Parameters.AddWithValue("@sdate", sdate); 
cmd.Parameters.AddWithValue("@edate", edate); 
// etc ... 
9

Prova questo

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

Se la prima cella restituito è una null, il risultato NET sarà DBNull.Value

Se non le cellule vengono restituiti, il risultato NET sarà null; non è possibile chiamare ToString() su un null. Ovviamente è possibile catturare ciò che restituisce ExecuteScalar ed elaborare lo null/DBNull/altri casi separatamente.

Dato che si sta raggruppando, si potrebbe presumibilmente avere più di un gruppo. Francamente non sono sicuro che ExecuteScalar sia la tua migliore opzione qui ...


aggiuntive: lo sql nella questione è un male in molti modi:

  • sql injection
  • internazionalizzazione (Speriamo che il client e il server sono d'accordo su quello che una data assomiglia)
  • concatenazione inutile in dichiarazioni separate

Suggerisco caldamente di parametrizzare; magari con qualcosa come "dapper" per rendere più facile:

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

tutti i problemi risolti, tra cui lo scenario "nessuna riga". Le date sono passate come date (non stringhe); il foro di iniezione viene chiuso mediante l'uso di un parametro. Ottieni anche il riutilizzo del piano di query come bonus aggiuntivo. Il group by qui è ridondante, BTW - se c'è un solo gruppo (tramite la condizione di uguaglianza), si potrebbe anche selezionare COUNT(1).

+0

Grazie per la bella spiegazione, la prima volta che ho sentito parlare di 'dapper', impara di nuovo oggi –

+1

@Satindersingh è disponibile gratuitamente su nuget: https://www.nuget.org/packages/Dapper –

4

Il valore non è nullo, ma DBNull.Value.

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

Per lavorare con NpgsqlCommand o l'uso sqlCommand di serie:

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

funzione di server isnull Utilizzare 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; 
} 
0

provate questo, se nulla impostato 0 o qualcosa

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