错误-SqlDateTime溢出。必须介于1/1/1753 12:00:00 AM和12/31/9999 11:59:59 PM之间


80

我一直在使用我编写的这段代码,它以这种最不清楚的方式工作。我希望在数据库中插入一行,其中包括两列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");

仍然是同样的错误,奇怪的是,上述技巧适用于第一次插入数据库,但此后失败。有什么想法吗?


发布您的代码。另外,您可能会考虑只检查linq的底层构造。
2009年

Answers:


86

DateTimeC#中的A是值类型,而不是引用类型,因此不能为null。但是,它可以DateTime.MinValue是超出SQL ServerDATETIME数据类型范围的常数。

值类型保证始终具有(默认)值(零),而无需始终进行显式设置(在这种情况下为DateTime.MinValue)。

结论是您可能有一个未设置的DateTime值,您正试图将其传递给数据库。

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

datetime
1753年1月1日至9999年12月31日之间的日期和时间数据,精度为三分之一秒(相当于3.33毫秒或0.00333秒)。值四舍五入为.000,.003或.007秒

smalldatetime
1900年1月1日到2079年6月6日之间的日期和时间数据,精确到分钟。小于等于29.998秒的smalldatetime值将四舍五入到最接近的分钟;29.999秒或更高的值将四舍五入到最接近的分钟。

MSDN:SQL Server DateTime和SmallDateTime


最后,如果发现自己将C#DateTime作为字符串传递给sql,则需要按以下格式设置其格式,以保持最大精度并防止sql server抛出类似错误。

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

更新(8年后)

考虑使用日期范围和时间范围DateTime2与.net更好地对齐的sql数据类型DateTime0001-01-01 through 9999-12-3100:00:00 through 23:59:59.9999999

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

MSDN datetime2(Transact-SQL)


6
感谢您提供有关DateTimeC#中不可为空的指针!
Tomas Aschan 2011年

80

我发现在许多与数据库相关的错误之后,对于SQL最小/最大日期,使用以下命令效果很好:

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

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

2
这应该获得最多的选票,也是正确的答案。
塔哈·雷曼·西迪基

不过请注意,DateTime.MaxValue和之间有一些滴答差异SqlDateTime.MaxValue.Value。SQL Server 2014和SQL Server 2016(没有检查其他人)接受DateTime.MaxValue哪个-足够有趣-比更大SqlDateTime.MaxValue.Value
曼弗雷德

10

当比较.Net DateTime和SqlDateTime.MinValue或MaxValue时要当心。例如,以下将引发异常:

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

原因是MinValue返回的是SqlDateTime,而不是DateTime。因此,.Net尝试将dte转换为SqlDateTime进行比较,并且由于它在可接受的SqlDateTime范围之外,因此引发异常。

一种解决方案是将您的DateTime与SqlDateTime.MinValue进行比较。价值


1
也可以使用SqlDateTime.MinValue.ValueSqlDateTime.MaxValue.Value两者均为type的选项DateTime。不知道这些是什么时候引入的。不过请注意,DateTime.MaxValue和之间有一些滴答差异SqlDateTime.MaxValue.Value。SQL Server 2014和SQL Server 2016(未检查其他人)接受DateTime.MaxValue哪个-有趣的是大于SqlDateTime.MaxValue.Value
曼弗雷德

9

两列的代码看起来不错。在该映射类上查找其他任何datetime列。另外,启用登录数据上下文以查看查询和参数。

dc.Log = Console.Out;

DateTime初始化为c#的0-0001-01-01。linqtosql通过sql字符串常量'0001-01-01'将其传输到数据库。Sql无法从该日期解析T-Sql datetime。

有几种方法可以解决此问题:

  • 确保使用SQL可以处理的值初始化所有日期时间(例如Sql的0:1900-01-01)
  • 确保可能会被忽略的任何日期时间为可空的日期时间

1
我通常使用1970-01-01,这是计算机时间的通用纪元(unix TIME_T和JavaScript)
Tracker1

感谢您提供将日志重定向到Console.Out的提示。
1月Aagaard

8

如果尝试将DateTime类型的变量设置为null,则会发生此错误。将该变量声明为可空值,即DateTime?。这样可以解决问题。


1
这是我溢出的答案,我在表上还有第二个日期,我没有提供值,因此一旦将其设置为可空值,插入就起作用了。谢谢!
mkimmet

3

有时为了减少编写代码,SQL服务器通常通过将字段的默认值设置为GETDATE()或来设置插入时的日期,时间和ID等字段。NEWID()

在这种情况下,自动产生的价值,应将实体类中那些字段的“属性设置为true。

这样,您无需在代码中设置值(防止能耗!!!),再也不会看到该异常。


2

使用扩展方法

 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();

1

这通常意味着将空值而不是所需的值发布到查询中,您可以尝试运行SQL事件探查器以查看从linq传递给SQL Server的确切信息。


1

通常,执行DateTime转换或解析时会出现这种错误。检查托管应用程序的服务器中的日历设置,主要是时区和短日期格式,并确保将其设置为该位置的正确时区。希望这能解决问题。


0

我看到的是同一件事。该错误不会在插入行时发生,而是在更新时发生。我引用的表有两个DateTime列,两个列都不可以为空。

我已经弄清楚了该场景,直到获取该行并立即保存它(没有数据更改)。获取工作正常,但更新失败。

我们正在使用NHibernate 3.3.1.4000


0

如果您使用的是NHibernate,请检查是否在映射中将可为空的适当DateTime属性设置为可为空。


0

如果您将Datetime设置为null,例如DateTime?在您的模型中不会引发异常。我就这样解决了问题


0

就我而言,出现此错误是因为“表日期”列不可为空

如下:

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

为避免此错误,请将其设置为可为空

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

-3

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 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.