Подтвердить что ты не робот

Возвращаемое значение с использованием результата String = Ошибка Command.ExecuteScalar() возникает, когда результат возвращает null

Я хочу получить значение 1-й строки 1-й ячейки из базы данных, она хорошо работает с нижеприведенным кодом. Но когда результат не найден, он выбрасывает исключение.

Как обращаться с 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;
    }
4b9b3361

Ответ 1

Нет необходимости продолжать вызов .ToString(), поскольку getValue уже является строкой.

Кроме того, эта строка может быть вашей проблемой:

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

Если строк нет, t23 возвращает null, поэтому вам нужно выполнить некоторую проверку.

Например:

var firstColumn = cmd.ExecuteScalar();

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

Ответ 2

Если первая возвращаемая ячейка является null, результатом .NET будет DBNull.Value

Если никакие ячейки не возвращаются, результат в .NET будет null; вы не можете вызвать ToString() на null. Вы можете, конечно, захватить то, что ExecuteScalar возвращает и обрабатывать null/DBNull/другие случаи отдельно.

Поскольку вы группируете и т.д., предположительно потенциально может иметь более одной группы. Честно говоря, я не уверен, что ExecuteScalar - ваш лучший вариант здесь...


Дополнительно: sql в вопросе плох по-разному:

  • SQL-инъекция
  • интернационализация (позвольте надеяться, что клиент и сервер согласятся на то, как выглядит дата)
  • ненужная конкатенация в отдельных операторах

Я настоятельно рекомендую вам параметризовать; возможно, с чем-то вроде "dapper", чтобы сделать его легким:

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

все проблемы решены, включая сценарий "без строк". Даты передаются как даты (не строки); отверстие для инъекции закрывается с использованием параметра. Вы получаете повторное использование плана запроса в качестве дополнительного бонуса. group by здесь избыточен, BTW - если есть только одна группа (через условие равенства), вы можете просто выбрать COUNT(1).

Ответ 3

Попробуйте этот

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

Ответ 4

Вы можете использовать, например, следующие

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

Ответ 5

Значение не равно null, но DBNull.Value.

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

Ответ 6

попробуйте следующее:

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

Ответ 7

Это должно работать:

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

Ответ 8

Использовать функцию 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;
}

Ответ 9

Существует расширенная функция С#, используйте это "?." , string getValue = cmd.ExecuteScalar()?. ToString(); всем спасибо.

Ответ 10

Для работы с NpgsqlCommand или стандартным sqlCommand используйте:

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

Ответ 11

Попробуйте это, если нулевое значение 0 или что-то

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