Пытаясь вставить поле DateTime.Now в Date/Time, появляется сообщение "Ошибка несоответствия типа данных"

Если я попытаюсь записать дату и время в запись в базе данных MS-Access, просто, как этот

cmd.CommandText = "INSERT INTO [table] ([date]) VALUES (?)";
cmd.Parameters.AddWithValue("?", DateTime.Now);

Я получаю исключение: "Несоответствие типов данных в выражении критериев".

Может ли кто-нибудь сказать мне, почему? Что здесь не так?

После небольшого эксперимента, я обнаружил, что могу заставить его работать, если я пишу

OleDbParameter parm = new OleDbParameter("?", OleDbType.Date);
parm.Value = DateTime.Now;
cmd.Parameters.Add(parm);

но делать это как будто кажется менее аккуратным, менее простым. Почему это необходимо? Могу ли я пропустить что-то простое?

Ответ 1

Проблема несоответствия в выражении критериев связана с OleDbType, назначенным параметру, используемому для представления значения DateTime.Now, когда вы вызываете AddWithValue.

OleDbType, выбранный AddWithValue, DBTimeStamp, но Access хочет a OleDbType.Date.

http://support.microsoft.com/kb/320435

Поиск в NET я нашел еще один подсказку. Основная проблема заключается в OleDbParameter, который не может обрабатывать миллисекундную часть DateTime.Now. Вероятно, для параметра OleDbType должно быть указано, что часть миллисекунд опущена. Я также обнаружил, что вставка также работает с типом DBTimeStamp, если мы удалим миллисекунды с даты.

cmd.Parameters.AddWithValue("?", GetDateWithoutMilliseconds(DateTime.Now));

private DateTime GetDateWithoutMilliseconds(DateTime d)
{
    return new DateTime(d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second);
}

О, ну, ожидая кого-то, кто объяснит это лучше.

Ответ 2

Простейшее утверждение требует, чтобы движок db использовал свою функцию Now() для получения текущего значения Date/Time. Или вы можете использовать функцию Date(), если вас не интересует время суток; Date() на самом деле даст вам полночь как время суток.

INSERT INTO [table] ([date]) VALUES (Now());

IOW, вам не нужно беспокоиться о том, чтобы массировать значение Date/Time в .Net, чтобы вставить его в ваш db доступа.

Если вам нужен оператор INSERT, который включает в себя литеральное значение даты, используйте разделители даты #. Итак, чтобы вставить сегодня дату:

INSERT INTO [table] ([date]) VALUES (#2013-04-25#);