2013-05-20 4 views
20

データベースから1行目の1番目のセルの値をフェッチしたい場合、以下のコードでうまく動作します。しかし、結果が見つからない場合、例外がスローされます。文字列を使用した戻り値result =結果がnullを返すとCommand.ExecuteScalar()エラーが発生する

DBNullで処理する方法。
クエリを変更する必要がありますか?彼らはレコードがない場合、いくつかの値を返しますか?

System.NullReferenceException:オブジェクト参照がオブジェクトのインスタンスに設定されていません。

コード:

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

どこに例外がスローされますか? –

+1

例外は 'string getValue = cmd.ExecuteScalar()。ToString();'というエラーが発生した場合、結果は –

+4

btwであり、**本当に**クエリをビルドするには悪い方法です。クリアと露骨なSQL注入穴;国際化の問題と不要な中間文字列もあります。私はあなたがsqlを通常どのようにしているのではないかと願っています。 –

答えて

44

です既に文字列。この行は、おそらくあなたの問題である可能性は別として

、ということ:

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

行がない場合は.ExecuteScalarはそうあなたには、いくつかのチェックを行う必要がありnullを返します。例えば

var firstColumn = cmd.ExecuteScalar(); 

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

これはうまくいきました。Naresh Parmarの答えは、文字列のチェックを追加することによって私のために働いていました。 " –

+1

またはConvert.ToString(cmd.ExecuteScalar());を使用することができます - これは' String.Empty'を返しますif値は 'null'です。 – DrNachtschatten

5

あなたはこの試みる次

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

@Satindersinghどこで試しましたか?どのようなコードを使用しましたか?質問のコードはこれを示していません... –

+0

これはうまくいくはずです。 –

+0

はいこれもうまくいき、前のことをお詫び申し上げますcmnt –

2

のように使用することができます。getValueとして.ToString()を呼び出して維持する必要はありません

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

は、これは動作するはずです:

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

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

をまた、私はあなたのクエリでパラメータを使用してお勧めする、(単なる提案)のようなもの:

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

これを試してください

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

返される最初のセルはnullある場合、.NETの結果には、細胞がを返されない場合、.NETの結果はnullなりDBNull.Value

あろう。 nullToString()と電話することはできません。もちろんExecuteScalarが返すものをキャプチャしてnull/DBNull /その他のケースを別々に処理することもできます。

あなたはグループ化しているので、おそらく複数のグループを持つ可能性があります。率直に言って、ExecuteScalarはあなたの最高のオプションです


追加:問題のSQLは、多くの点で悪い:

  • SQLインジェクション
  • 国際(のは、クライアントとサーバーの日付がどのように見えるかについて合意を期待しましょう)
  • 別のステートメントでの不要な連結

パラメータ化することを強くお勧めします。

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

"no rows"シナリオを含め、すべての問題が解決されました。日付は(文字列ではなく)日付として渡されます。パラメータを用いて噴射孔を閉鎖する。追加のボーナスとしてクエリープランの再利用も得られます。 group byはここでは冗長ですが、BTW - グループが1つしかない場合(同等条件によって)、COUNT(1)を選択することもできます。

+0

すてきな説明をしてくれてありがとう、初めてダッペルについて聞いて、今日新しいことを学ぶ –

+1

@Satindersinghナゲットで自由に入手できます:https://www.nuget.org/packages/Dapper –

4

値はNULLではなく、DBNull.Valueです。 NpgsqlCommandまたは標準SqlCommandオブジェクトを使用して動作するように

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

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

使用SQLサーバーのIsNull関数

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

ヌルが0か何か

return command.ExecuteScalar() == DBNull.Value ? 0 : (double)command.ExecuteScalar(); 
を設定している場合、この方法を試してください。
関連する問題