SQL DateTime Vs.C # Datetime MinDate - PullRequest
       1

SQL DateTime Vs.C # Datetime MinDate

0 голосов
/ 16 апреля 2019

У меня есть база данных SQL Server, в одной из моих таблиц LatestData есть столбец, который не может содержать nullable DATETIME со значением по умолчанию 01/01/1970.См. Код под точным кодом T-SQL для этого столбца.

[MyDateTime] DATETIME DEFAULT (CONVERT([DATETIME], CONVERT([DATE], '1970/01/01 00:00AM', (0)), (0))) NOT NULL

Когда эта таблица добавляется в код нашего сервера (C #) через модель данных .EDMX, поле выглядит следующим образом:

public System.DateTime MyDateTime { get; set; }

Я добавляю новые данные вэта таблица через C #, но на момент добавления строки мой столбец MyDateTime не содержит никаких данных.

Поскольку столбец равен Not Null, мое поле MyDateTime автоматически устанавливается на 01/01/0001.

При попытке добавить эту дату в мой столбец DateTime выдается следующая ошибка:

System.Data.SqlClient.SqlException: преобразование типа данных datetime2 в данные datetimeТип привел к значению вне допустимого диапазона.

После некоторых исследований я обнаружил, что C # Datetime MinDate - 01/01/0001, тогда как SQL Server DATETIME - 01/01/ 1753, и это вызывает ошибку.

Код C # передает «пустое» поле как 01/01/0001 в базу данных, которая затем пытается преобразовать его.Это, очевидно, неудачно.

Есть ли способ для базы данных узнать, чтобы вернуться к значению по умолчанию, вместо того, чтобы пытаться сначала преобразовать DATETIME, или сделать это в случае сбоя преобразования?

Я знаю, что мог бы установить для столбца в Datatable значение DateTime2 или указать дату для этого столбца перед добавлением его через C #, но это не лучший способ сделать это?

Заранее спасибо за любую помощь.

Ответы [ 2 ]

1 голос
/ 16 апреля 2019

Это еще одна причина, по которой вы предпочитаете DateTime2, а не DateTime - тип данных DateTime2 поддерживает тот же диапазон дат, что и структура DateTime платформы .Net - с 1 января 0001 по 31 декабря 9999 года.

Измените тип данных MyDateTime на DateTime2, а значение по умолчанию - 0001-01-01:

ALTER TABLE MyTable
    ALTER COLUMN MyDateTime DateTime2 NOT NULL

Чтобы изменить ограничение по умолчанию, вам нужно удалить его и заново создать. Это можно легко сделать с помощью SSMS (просто найдите его, щелкните правой кнопкой мыши и отпустите), но с помощью T-SQL вам придется использовать один из ответов из этого поста , поскольку вы не указали его имя. Сделав это, вы можете добавить его (на этот раз с правильным именем):

ALTER TABLE MyTable
    ADD CONSTRAINT DF_MyDateTime DEFAULT ('0001-01-01') FOR MyDateTime 
1 голос
/ 16 апреля 2019

Если 1970-01-01 является приемлемым без установленной даты , то поместите ее в C #:

public System.DateTime MyDateTime { get; set; } = new DateTime(1970, 1, 1);

Я думаю, что вы должны рассмотреть вопрос о разрешении пустых значений в столбце и сделать это:

public System.DateTime? MyDateTime { get; set; }

Вы запросили исправление только для SQLS; единственное, о чем я могу подумать сейчас, это использовать хранимую процедуру для вставки:

--set up an example table with a datetime
create table a(a datetime);
--test that an insert doesnt work out
insert into a(a) values(cast('0001-01-01' as datetime2)); --error!
go
--make a procedure to do the insert logic/conversion
CREATE PROCEDURE a_ins(@a DATETIME2) 
AS
BEGIN
  INSERT INTO a (a) 
  --if the date is less than the column will support, default it
  SELECT case when @a < CAST('1753-01-01' as datetime2) THEN cast('1970-01-01' as datetime) else cast(@a as datetime) end
END
GO
--quick run the procedure to test
DECLARE @dt2 DATETIME2 = cast('0001-01-01' as datetime2);
EXEC a_ins @dt2 --inserts 1970

Вы можете выбрать, какой диапазон дат вы хотите вставить - может быть, что-нибудь до 1970 года станет 1970-м, может быть, что-нибудь до 1753 года, может быть, только 0001-01-01 ... вы выбираете в логике «случай, когда»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...