Возвращаемое значение с использованием результата 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;
}
Ответы
Ответ 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();