#c# #sql-server #datetime #casting
#c# #sql-сервер #datetime #Кастинг
Вопрос:
Я выполняю простую инструкцию SELECT и пытаюсь вернуть значение из столбца DateTime из таблицы SQL Server 2012. Проблема в том, что когда я возвращаю нулевое значение DateTime, я не знаю, как управлять этим с помощью моего кода ниже.
dtTrainingEnd = (DateTime)reader["TrainingEnd"];
Последние несколько дней я искал ответ и не могу найти что-то, что мне поможет. Я нашел похожие сообщения, но все еще не могу понять, как они могут мне помочь. Не могли бы вы, пожалуйста, объяснить, как я могу проверить, является ли значение datetime, возвращаемое из базы данных, нулевым?
SqlConnection connRead = new SqlConnection(connReadString);
SqlCommand comm = new SqlCommand();
SqlDataReader reader;
string sql;
DateTime dtTrainingEnd = DateTime.Now;
int iTrainingSwipeID = 123;
sql = "SELECT TrainingEnd FROM TrainingSwipe WHERE TrainingSwipeID = " iTrainingSwipeID;
comm.CommandText = sql;
comm.CommandType = CommandType.Text;
comm.Connection = connRead;
connRead.Open();
reader = comm.ExecuteReader();
while (reader.Read())
{
dtTrainingEnd = (DateTime)reader["TrainingEnd"];
}
connRead.Close();
Комментарии:
1. Примечание к типу DateTime, DateTime — это тип значения (struct), при извлечении значения null оно само устанавливает значение по умолчанию. Значение по умолчанию этого типа равно ’01/01/0001′.
2. Если база данных допускает нули, то и ваш код должен делать то же самое. Рассмотрите возможность использования типов с нулевым значением, в которых задействованы эти столбцы.
Ответ №1:
Если это возможно null
, вы могли бы использовать тип с нулевым значением … в данном случае DateTime?
тип:
while (reader.Read())
{
dtTrainingEnd = ((DateTime?)reader["TrainingEnd"]) ?? some_default_date;
}
connRead.Close();
Или просто протестируйте null
, если вы предпочитаете это делать:
while (reader.Read())
{
var endDate = reader["TrainingEnd"];
dtTrainingEnd = (endDate == null) ? some_default_date : (DateTime)endDate;
}
connRead.Close();
В обоих случаях выше, я предположил, что вы хотите, dtTrainingEnd
чтобы содержать что-то , если дата имеет значение null в базе данных, поэтому some_default_date
некоторые даты и времени по умолчанию.
Или, если вы хотите оставить dtTrainingEnd
в покое, если значение равно NULL, то просто не устанавливайте его в этом случае:
while (reader.Read())
{
if ((reader["TrainingEnd"]) != null)
dtTrainingEnd = (DateTime)reader["TrainingEnd"];
}
connRead.Close();
*** В зависимости от способа подключения к вашей базе данных, возможно, придется заменить null
на DBNull.Value
Комментарии:
1. более широким шаблоном мог бы быть
reader["field"] as DateTime? ?? some_default_date
; это будет полезно для обработки того же сценария с таблицами данных, какnull
становитсяDBNull.Value
2. @Grant, во втором примере, что будет сохранено в dtTrainingEnd, если значение базы данных равно NULL? Другими словами, каким будет оператор if, чтобы увидеть, является ли datetime нулевым или нет? Извините, я совершенно не разбираюсь в этой теме.
3. @Grant, хорошо, я думаю, я понял. Большое вам спасибо за ваше терпение и помощь. 😀
4. @Grant, когда я ввожу код, я получаю сообщение об ошибке «System. Исключение IndexOutOfRangeException: завершение обучения» для оператора if «if ((reader[«Завершение обучения»]) != null)». Есть идеи? Я не могу поверить, что в c # так сложно определить, является ли datetime нулевым … : (
5. @Grant, по какой-то причине для меня проверка «== null» возвращала not null для всех записей из базы данных, которые не были null. Итак, небольшой поиск нашел это для меня «== DBNull. Значение «сделало свое дело. Не уверен, в чем разница, но я подумал, что упомяну об этом на случай, если у кого-то еще возникнет такая же проблема.
Ответ №2:
С помощью SQL вы можете выполнить SELECT Coalesce(TrainingEnd,0), и если оно равно null, у вас будет дата 1900-01-01…