错误 – SqlDateTime溢出。 必须介于1/1/1753 12:00:00 AM和12/31/9999 11:59:59 PM之间
我一直在使用我写的这段代码,它以这种最不清晰的方式工作。 我希望在包含两列DateTime的数据库中插入一行:
myrow.ApprovalDate = DateTime.Now myrow.ProposedDate = DateTime.Now
然而,当我更新数据库时,我收到这个错误:
SqlDateTime溢出。 必须介于1/1/1753 12:00:00 AM和12/31/9999 11:59:59 PM之间。
我甚至尝试从数据库中复制插入的值,并将其硬编码到正在更新的对象中:
// I copied this value from the DB myrow.ApprovalDate = Convert.ToDateTime("2008-12-24 00:00:00.000");
还有一个相同的错误,奇怪的部分是,上面的技巧工作的第一次插入到数据库,但从那里失败。 任何想法是怎么回事?
C#中的DateTime
是一个值types,而不是引用types,因此不能为空。 但是它可以是常量DateTime.MinValue
,它不在Sql Server DATETIME
数据types的范围内。
值types保证始终有一个(默认)值(零),而不总是需要明确设置(在这种情况下DateTime.MinValue)。
结论是你可能有一个未设置的date时间值,你试图传递给数据库。
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
关于Sql Server
约会时间
date和时间数据从1753年1月1日到9999年12月31日,精确到百分之一秒(相当于3.33毫秒或0.00333秒)。 数值被四舍五入到.000,.003或.007秒的增量SMALLDATETIME
date和时间数据从1900年1月1日到2079年6月6日,准确到分钟。 小于或等于29.998秒的smalldatetime值会舍入到最接近的分钟; 29.999秒或更高的值被四舍五入到最接近的分钟。
MSDN: Sql Server的DateTime和SmallDateTime
最后,如果您发现自己将C# DateTime
作为string传递给sql,则需要按照以下格式进行格式化,以保持最高精度并防止sql server发出类似的错误。
string sqlTimeAsString = myDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fff");
更新(8年后)
考虑使用sql DateTime2
数据types,该数据types的date范围为0001-01-01 through 9999-12-31
,时间范围为00:00:00 through 23:59:59.9999999
string dateTime2String = myDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffffff");
MSDN datetime2(Transact-SQL)
我发现在很多数据库相关的错误之后,对SQL最小/最大date使用以下工作相当不错:
DateTime rngMin = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue; DateTime rngMax = (DateTime)System.Data.SqlTypes.SqlDateTime.MaxValue;
你有两列的代码看起来不错。 查找该映射类上的任何其他date时间列。 另外,启用datacontext上的日志logging以查看查询和参数。
dc.Log = Console.Out;
DateTime初始化为c#的0 – 即0001-01-01。 这是由linqtosql通过SQLstring文字“0001-01-01”传输到数据库。 Sql不能从这个dateparsingT-SQLdate时间。
有几个方法可以解决这个问题:
- 确保使用SQL可以处理的值初始化所有date时间(如Sql的0:1900-01-01)
- 确保可能偶尔省略的date时间是可以为空的date时间
当将.Net DateTime与SqlDateTime.MinValue或MaxValue比较时,请小心。 例如,以下将引发exception:
DateTime dte = new DateTime(1000, 1, 1); if (dte >= SqlDateTime.MinValue) //do something
原因是MinValue返回一个SqlDateTime,而不是DateTime。 所以.net试图将dte转换为SqlDateTime进行比较,因为它超出了可接受的SqlDateTime范围,所以会抛出exception。
对此的一个解决scheme是比较你的DateTime和SqlDateTime.MinValue。 价值 。
有时,为了编写更less的代码,通过将字段的缺省值设置为GETDATE()
或NEWID()
,SQL Server将使用SQL Server设置字段,如插入date,时间和ID。
在这种情况下,实体类中这些字段的Auto Generated Value属性应该设置为true。
这样你就不需要在代码中设置值(防止能源消耗!!!),也不会看到这个exception。
如果您尝试将DateTimetypes的variables设置为null,则会发生此错误。 声明variables为空,即DateTime? 。 这将解决问题。
这通常意味着将null发布到查询中,而不是您期望的值,您可以尝试运行SQL Profiler以准确查看从linq传递给SQL Server的内容。
我看到同样的事情。 错误不会发生在插入行上,而是发生在更新上。 我引用的表有两个不能为空的DateTime列。
我得到的情况下得到的行,并立即保存它(没有数据更改)。 得到工作正常,但更新失败。
我们使用的是NHibernate 3.3.1.4000
通常这种错误来自你做date时间转换或parsing。 检查托pipe应用程序的服务器中的日历设置,主要是时区和短date格式,并确保将其设置为位置的正确时区。 希望这可以解决这个问题。
使用扩展方法
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();
如果你使用NHibernate的ORM检查你的date时间文件是可空的,并在你的NHibernate地图文件设置为空。
我有这个问题,并尝试了很多时间来检查所有的代码,并最终find它。
DateTime.MinValue和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