webentwicklung-frage-antwort-db.com.de

Rückgabewert using String result = Der Command.ExecuteScalar () - Fehler tritt auf, wenn das Ergebnis null zurückgibt

Ich möchte 1. Zeile 1. Zellwert aus der Datenbank abrufen, die mit dem folgenden Code gut funktioniert. Wenn jedoch kein Ergebnis gefunden wird, löst es eine Ausnahme aus.

Wie geht man mit DBNull um?.
Soll ich meine Abfrage ändern? welche geben einen Wert zurück, wenn sie keinen Datensatz haben?

System.NullReferenceException: Die Objektreferenz ist nicht auf eine Instanz eines Objekts festgelegt.

Code:

    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;
    }
24
Satinder singh

Es ist nicht notwendig, .ToString() weiter aufzurufen, da getValue bereits eine Zeichenfolge ist.

Abgesehen davon könnte diese Zeile möglicherweise Ihr Problem sein:

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

Wenn keine Zeilen vorhanden sind, gibt .ExecuteScalarnull zurück, sodass Sie einige Überprüfungen durchführen müssen.

Zum Beispiel:

var firstColumn = cmd.ExecuteScalar();

if (firstColumn != null) {
    result = firstColumn.ToString();
}
55
Darren

Wenn die erste zurückgegebene Zelle eine null ist, lautet das Ergebnis in .NET DBNull.Value

Wenn keine Zellen zurückgegeben werden , lautet das Ergebnis in .NET null; Sie können ToString() nicht für eine null aufrufen. Sie können natürlich erfassen, was ExecuteScalar zurückgibt, und die null/DBNull/andere Fälle separat verarbeiten.

Da Sie usw. gruppieren, könnten Sie möglicherweise mehr als eine Gruppe haben. Ehrlich gesagt bin ich mir nicht sicher, ob ExecuteScalar hier die beste Option ist ...


Zusätzlich: Die SQL in der Frage ist in vielerlei Hinsicht schlecht:

  • sQL-Injektion
  • internationalisierung (wir hoffen, dass sich Client und Server einig sind, wie ein Datum aussieht)
  • unnötige Verkettung in separaten Anweisungen

Ich empfehle Ihnen dringend zu parametrieren; vielleicht mit so etwas wie "dapper", um es einfach zu machen:

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

alle Probleme gelöst, einschließlich des Szenarios "Keine Zeilen". Die Datumsangaben werden als Datumsangaben (nicht als Zeichenfolgen) übergeben. Das Injektionsloch wird mit einem Parameter geschlossen. Sie können den Abfrageplan auch als zusätzlichen Bonus wiederverwenden. Der group by ist hier redundant. Übrigens - Wenn es nur eine Gruppe gibt (über die Gleichheitsbedingung), können Sie auch COUNT(1) auswählen.

18
Marc Gravell

Probier diese

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

Sie können wie folgt verwenden

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

Der Wert ist nicht null, sondern DBNull.Value.

object value = cmd.ExecuteScalar();
if(value == DBNull.Value)
4
Jānis

versuche dies : 

 string getValue = Convert.ToString(cmd.ExecuteScalar());
2
Naresh Parmar

Das sollte funktionieren:

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

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

Ich würde auch die Verwendung von Parametern in Ihrer Abfrage vorschlagen, etwa (nur einen Vorschlag):

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 ...
1

Verwenden Sie die isnull-Funktion von SQL Server

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
hussien

Es gibt eine erweiterte Funktion von c #, verwenden Sie das '?.' . string getValue = cmd.ExecuteScalar () ?. ToString (); alles andere.

0
Muzafar Hussain