错误-SqlDateTime 溢出。必须在1/1/175312:00:00 AM 和12/31/999911:59:59 PM 之间

我一直在使用我写的这段代码,它的工作方式非常不明确。我希望在数据库中插入一行,其中包含两列 DateTime:

myrow.ApprovalDate = DateTime.Now
myrow.ProposedDate = DateTime.Now

然而,当我更新数据库时,我收到了这个错误:

SqlDateTime 溢出。必须在1/1/175312:00:00 AM 和12/31/999911:59:59 PM 之间。

我甚至尝试从数据库中复制一个插入的值,并将其硬编码到正在更新的对象中:

// I copied this value from the DB
myrow.ApprovalDate =  Convert.ToDateTime("2008-12-24 00:00:00.000");

仍然是同样的错误,奇怪的是上面的技巧在第一次向 DB 插入时起作用了,但是从那时起就失败了。知道是怎么回事吗?

292328 次浏览

That usually means a null is being posted to the query instead of your desired value, you might try to run the SQL Profiler to see exactly what is getting passed to SQL Server from linq.

The code you have for the two columns looks ok. Look for any other datetime columns on that mapping class. Also, enable logging on the datacontext to see the query and parameters.

dc.Log = Console.Out;

DateTime is initialized to c#'s 0 - which is 0001-01-01. This is transmitted by linqtosql to the database via sql string literal : '0001-01-01'. Sql cannot parse a T-Sql datetime from this date.

There's a couple ways to deal with this:

  • Make sure you initialize all date times with a value that SQL can handle (such as Sql's 0 : 1900-01-01 )
  • Make sure any date times that may occasionally be omitted are nullable datetimes

A DateTime in C# is a value type, not a reference type, and therefore cannot be null. It can however be the constant DateTime.MinValue which is outside the range of Sql Servers DATETIME data type.

Value types are guaranteed to always have a (default) value (of zero) without always needing to be explicitly set (in this case DateTime.MinValue).

Conclusion is you probably have an unset DateTime value that you are trying to pass to the database.

DateTime.MinValue = 1/1/0001 12:00:00 AM
DateTime.MaxValue = 23:59:59.9999999, December 31, 9999,
exactly one 100-nanosecond tick
before 00:00:00, January 1, 10000

MSDN: DateTime.MinValue


Regarding Sql Server

datetime
Date and time data from January 1, 1753 through December 31, 9999, to an accuracy of one three-hundredth of a second (equivalent to 3.33 milliseconds or 0.00333 seconds). Values are rounded to increments of .000, .003, or .007 seconds

smalldatetime
Date and time data from January 1, 1900, through June 6, 2079, with accuracy to the minute. smalldatetime values with 29.998 seconds or lower are rounded down to the nearest minute; values with 29.999 seconds or higher are rounded up to the nearest minute.

MSDN: Sql Server DateTime and SmallDateTime


Lastly, if you find yourself passing a C# DateTime as a string to sql, you need to format it as follows to retain maximum precision and to prevent sql server from throwing a similar error.

string sqlTimeAsString = myDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fff");

Update (8 years later)

Consider using the sql DateTime2 datatype which aligns better with the .net DateTime with date range 0001-01-01 through 9999-12-31 and time range 00:00:00 through 23:59:59.9999999

string dateTime2String = myDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffffff");

MSDN datetime2 (Transact-SQL)

Sometimes in order to write less code it is used to have SQL server set fields like date, time and ID on insert by setting the default value for fields to GETDATE() or NEWID().

In such cases Auto Generated Value property of those fields in entity classes should be set to true.

This way you do not need to set values in code (preventing energy consumption!!!) and never see that exception.

I find using the following works quite well for SQL min/max dates after many DB related errors:

DateTime rngMin = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue;


DateTime rngMax = (DateTime)System.Data.SqlTypes.SqlDateTime.MaxValue;

If you are using NHibernate, check that appropriate DateTime properties that are nullable are set to nullable in the mappings.

Beware when comparing a .Net DateTime to SqlDateTime.MinValue or MaxValue. For example, the following will throw an exception:

DateTime dte = new DateTime(1000, 1, 1);
if (dte >= SqlDateTime.MinValue)
//do something

The reason is that MinValue returns a SqlDateTime, not a DateTime. So .Net tries to convert dte to a SqlDateTime for comparison and because it's outside the acceptable SqlDateTime range it throws the exception.

One solution to this is to compare your DateTime to SqlDateTime.MinValue.Value.

I am seeing the same thing. The error does not happen on insert of a row but on an update. the table I am referencing has two DateTime columns neither of which are nullable.

I have gotten the scenario down to getting the row and immediately saving it (no data changes). The get works fine but the update fails.

We are using NHibernate 3.3.1.4000

Usually this kind of error comes when you do DateTime conversion or parsing. Check the calendar setting in the server where the application is hosted, mainly the time zone and short date format, and ensure it's set to the right time zone for the location. Hope this would resolve the issue.

DateTime.MinValue and DateTime.MaxValue

DateTime.MinValue = 1/1/0001 12:00:00 AM


DateTime.MaxValue = 23:59:59.9999999, December 31, 9999,


exactly one 100-nanosecond tick


before 00:00:00, January 1, 10000

This error occurs if you are trying to set variable of type DateTime to null. Declare the variable as nullable, i.e. DateTime? . This will solve the problem.

Use extension method

 public static object ToSafeDbDateDBnull(this object objectstring)
{
try
{
if ((DateTime)objectstring >= SqlDateTime.MinValue)
{
return objectstring;
}
else
{
return DBNull.Value;
}
}
catch (Exception)
{


return DBNull.Value;
}


}


DateTime objdte = new DateTime(1000, 1, 1);
dte.ToSafeDbDateDBnull();

If you put Datetime nullable like DateTime? in your model it doesn't throw exception.

I solved the problem like this in my case.

In my case this error was raised because table date column is not null-able

As below:

Create Table #TempTable(
...
ApprovalDate datatime not null.
...)

To avoid this error just make it null-able

 Create Table #TempTable(
...
ApprovalDate datatime null.
...)

Change your db column type to datetime2 and add this to your query/command constructor:

SqlMapper.AddTypeMap(typeof(DateTime), System.Data.DbType.DateTime2);

I had a model with DateTime, but my database-table-column was expecting nullable DateTime.

When inserting my model into the DB, my ORM supplied an empty field which resulted in SQL Server raising an SqlDateTime overflow exception. The solution was simply to make the model DateTime field nullable so that when the ORM inserts the field and nothing is there, it supplies a DBNull value instead of an empty field.

For context; I ran into this problem while using the Dapper ORM.