エラー-SqlDateTimeオーバーフロー。1/1/1753 12:00:00 AMから12/31/999911:59:59PMの間にある必要があります


82

私は自分が書いたこのコードを使用してきましたが、この最も不明確な方法で機能しています。DateTimeの2つの列を含む行をデータベースに挿入したいと思います。

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

それでも、データベースを更新すると、次のエラーが発生します。

SqlDateTimeオーバーフロー。1/1/1753 12:00:00 AMから12/31/999911:59:59PMの間にある必要があります。

挿入された値をデータベースからコピーして、更新されるオブジェクトにハードコーディングしてみました。

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

それでも同じエラーですが、奇妙な部分は、上記のトリックがDBへの最初の挿入では機能したが、それ以降は失敗したことです。何が起こっているのかアイデアはありますか?


コードを投稿してください。また、linqが隠れて構築しているものを調べることを検討することもできます。
NotMe 2009年

回答:


87

DateTimeC#のAは値型であり、参照型ではないため、nullにすることはできません。ただしDateTime.MinValue、SQLServerのDATETIMEデータ型の範囲外の定数にすることができます。

値型は、常に明示的に設定する必要がなく、常に(デフォルトの)値(ゼロ)を持つことが保証されています(この場合は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


SQLServerについて

datetime
1753年1月1日から9999年12月31日までの日付と時刻のデータ。精度は100分の1秒(3.33ミリ秒または0.00333秒に相当)です。値は、.000、.003、または.007秒の増分に丸められます

smalldatetime
1900年1月1日から2079年6月6日までの日付と時刻のデータ。正確に分単位で表示されます。29.998秒以下のsmalldatetime値は、最も近い分に切り捨てられます。29.999秒以上の値は、最も近い分に切り上げられます。

MSDN:SQL ServerDateTimeおよびSmallDateTime


最後に、C#DateTimeを文字列としてSQLに渡すことに気付いた場合は、最大の精度を維持し、SQLサーバーが同様のエラーをスローしないように、次のようにフォーマットする必要があります。

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

更新(8年後)

日付範囲と時間範囲でDateTime2.netDateTimeとより適切に整合するSQLデータ型の使用を検討してください0001-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#でnull許容にならないことについてのポインタをありがとう!
Tomas Aschan 2011

80

以下を使用すると、DB関連のエラーが多数発生した後のSQLの最小/最大日付に非常に適していることがわかります。

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

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

2
これは最も多くの票を獲得するはずであり、正解でもあります。
Taha Rehman Siddiqui 2013

間にいくつかのダニ差があること、しかし、注意してくださいDateTime.MaxValueSqlDateTime.MaxValue.Value。SQL Server2014およびSQLServer 2016(他のユーザーをチェックしませんでした)は、DateTime.MaxValueどちらが-おかしなことに-より大きいかを受け入れSqlDateTime.MaxValue.Valueます。
マンフレッド2017

10

.NetDateTimeをSqlDateTime.MinValueまたはMaxValueと比較する場合は注意してください。たとえば、次の場合は例外がスローされます。

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

その理由は、MinValueがDateTimeではなくSqlDateTimeを返すためです。そのため、.Netは比較のためにdteをSqlDateTimeに変換しようとしますが、許容可能なSqlDateTimeの範囲外であるため、例外がスローされます。

これに対する1つの解決策は、DateTimeをSqlDateTime.MinValueと比較することです。


1
使用するオプション、SqlDateTime.MinValue.ValueまたはSqlDateTime.MaxValue.Valueその両方がタイプであるオプションもありますDateTime。それらがいつ導入されたかわからない。間にいくつかのダニ差があること、しかし、注意してくださいDateTime.MaxValueSqlDateTime.MaxValue.Value。SQL Server2014とSQLServer 2016(他のユーザーをチェックしませんでした)はDateTime.MaxValueどちらを受け入れますか-面白いのはSqlDateTime.MaxValue.Value。よりも大きいです。
マンフレッド2017

9

2つの列のコードは問題ないようです。そのマッピングクラスで他の日時列を探します。また、データコンテキストへのログ記録を有効にして、クエリとパラメータを確認します。

dc.Log = Console.Out;

DateTimeは、c#の0(0001-01-01)に初期化されます。これは、linqtosqlによってSQL文字列リテラル「0001-01-01」を介してデータベースに送信されます。Sqlは、この日付からT-Sql日時を解析できません。

これに対処する方法はいくつかあります。

  • SQLが処理できる値(SQLの0:1900-01-01など)ですべての日時を初期化するようにしてください。
  • 時々省略される可能性のある日時がNULL可能日時であることを確認してください

1
私は通常、コンピューター時間の一般的なエポックである1970-01-01(unix TIME_TおよびJavaScript)を使用します
Tracker1 2009

ログをConsole.Outにリダイレクトするヒントをありがとう。
Jan Aagaard 2009年

8

このエラーは、DateTime型の変数をnullに設定しようとした場合に発生します。変数をnull許容として宣言しますつまり、DateTime?。これで問題は解決します。


1
これが私のオーバーフローへの答えでした。テーブルに値を指定していない2番目の日付があったので、null許容として設定すると、挿入が機能しました。ありがとう!
mkimmet 2016

3

記述するコードを減らすために、フィールドのデフォルト値をGETDATE()またはに設定することにより、SQLサーバーに挿入時に日付、時刻、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

これは通常、目的の値ではなくnullがクエリに送信されていることを意味します。SQLプロファイラーを実行して、linqからSQLServerに何が渡されているかを正確に確認してください。


1

通常、この種のエラーは、DateTime変換または解析を行うときに発生します。アプリケーションがホストされているサーバーのカレンダー設定(主にタイムゾーンと短い日付の形式)を確認し、場所に適したタイムゾーンに設定されていることを確認します。これで問題が解決することを願っています。


0

私は同じことを見ています。エラーは、行の挿入では発生しませんが、更新では発生します。私が参照しているテーブルには2つのDateTime列があり、どちらもnull許容ではありません。

行を取得してすぐに保存するというシナリオになりました(データは変更されません)。getは正常に機能しますが、更新は失敗します。

NHibernate3.3.1.4000を使用しています


0

NHibernateを使用している場合は、マッピングでnull許容の適切なDateTimeプロパティがnull許容に設定されていることを確認してください。


0

DateTimeをDateTimeのようにnull許容にする場合はどうなりますか?モデルでは、例外はスローされません。私の場合、このような問題を解決しました


0

私の場合、テーブルの日付列がnullに対応していないため、このエラーが発生しました

以下のように:

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

このエラーを回避するには、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 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.