오류-SqlDateTime 오버플로입니다. 1753 년 1 월 1 일 오전 12:00:00에서 9999 년 12 월 31 일 오후 11:59:59 사이 여야합니다.


82

저는 제가 작성한이 코드를 사용해 왔으며 가장 명확하지 않은 방식으로 작동하고 있습니다. DateTime의 두 열을 포함하는 데이터베이스에 행을 삽입하고 싶습니다.

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

그러나 데이터베이스를 업데이트하면 다음 오류가 발생합니다.

SqlDateTime 오버플로. 1753 년 1 월 1 일 오전 12:00:00에서 9999 년 12 월 31 일 오후 11:59:59 사이 여야합니다.

심지어 데이터베이스에서 삽입 된 값을 복사하여 업데이트중인 개체에 하드 코딩했습니다.

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

여전히 같은 오류이지만 이상한 부분은 위의 트릭이 DB에 대한 첫 번째 삽입에서 작동했지만 거기서부터 실패했다는 것입니다. 무슨 일이 일어나고 있는지 아이디어가 있습니까?


코드를 게시하십시오. 또한 linq가 내부적으로 무엇을 만들고 있는지 검사하는 것을 고려할 수 있습니다.
NotMe

답변:


87

DateTimeC #에서 A 는 참조 형식이 아닌 값 형식이므로 null 일 수 없습니다. 그러나 DateTime.MinValueSql Servers DATETIME데이터 유형 의 범위를 벗어난 상수 일 수 있습니다 .

값 유형은 항상 명시 적으로 설정할 필요없이 (이 경우 DateTime.MinValue) 항상 (기본값) 값 (0)을 갖도록 보장됩니다.

결론은 아마도 데이터베이스에 전달하려는 설정되지 않은 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 일까지의 300 분의 1 초 (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 #에서 Null을 허용하지 않는 것에 대한 포인터를 주셔서 감사합니다 !
토마스 Aschan

80

많은 DB 관련 오류 후 SQL 최소 / 최대 날짜에 대해 다음을 사용하면 매우 잘 작동합니다.

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

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

2
이것은 가장 많은 표를 얻었어야하며 정답이기도합니다.
Taha Rehman Siddiqui

사이 몇 틱 차이가 있다고하지만,주의 DateTime.MaxValue하고 SqlDateTime.MaxValue.Value. SQL Server 2014 및 SQL Server 2016 (다른 항목을 확인하지 않음) DateTime.MaxValueSqlDateTime.MaxValue.Value.
Manfred

10

.Net DateTime을 SqlDateTime.MinValue 또는 MaxValue와 비교할 때주의하십시오. 예를 들어 다음은 예외를 발생시킵니다.

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

그 이유는 MinValue가 DateTime이 아닌 SqlDateTime을 반환하기 때문입니다. 따라서 .Net은 비교를 위해 dte를 SqlDateTime으로 변환하려고 시도하고 허용 가능한 SqlDateTime 범위를 벗어 났기 때문에 예외가 발생합니다.

이에 대한 한 가지 해결책은 DateTime을 SqlDateTime.MinValue와 비교하는 것입니다. 가치 .


1
사용 옵션 SqlDateTime.MinValue.Value또는 SqlDateTime.MaxValue.Value둘 다 유형이 DateTime있습니다. 그것들이 언제 도입되었는지 모릅니다. 사이 몇 틱 차이가 있다고하지만,주의 DateTime.MaxValue하고 SqlDateTime.MaxValue.Value. SQL Server 2014 및 SQL Server 2016 (다른 항목을 확인하지 않음) DateTime.MaxValueSqlDateTime.MaxValue.Value.
Manfred

9

두 열에 대한 코드는 괜찮아 보입니다. 해당 매핑 클래스에서 다른 datetime 열을 찾습니다. 또한 쿼리 및 매개 변수를 보려면 데이터 컨텍스트에 대한 로깅을 활성화하십시오.

dc.Log = Console.Out;

DateTime은 0001-01-01 인 c #의 0으로 초기화됩니다. 이는 linqtosql에 의해 sql 문자열 리터럴 '0001-01-01'을 통해 데이터베이스로 전송됩니다. SQL은이 날짜에서 T-Sql datetime을 구문 분석 할 수 없습니다.

이를 처리하는 몇 가지 방법이 있습니다.

  • SQL이 처리 할 수있는 값으로 모든 날짜 시간을 초기화해야합니다 (예 : Sql의 0 : 1900-01-01).
  • 가끔 생략 될 수있는 날짜 시간이 nullable datetime 인지 확인하십시오.

1
나는 보통 컴퓨터 시간 (unix TIME_T 및 JavaScript)의 일반적인 시대 인 1970-01-01을 사용합니다.
Tracker1

Log를 Console.Out으로 리디렉션하는 팁에 감사드립니다.
Jan Aagaard

8

이 오류는 DateTime 유형의 변수 를 null 로 설정하려는 경우 발생합니다 . 변수를 nullable로 선언하십시오. 즉, DateTime? . 이것은 문제를 해결할 것입니다.


1
이것이 내 오버플로에 대한 대답이었고 테이블에 값을 제공하지 않은 두 번째 날짜가 있었으므로 nullable로 설정하면 삽입이 작동했습니다. 감사!
mkimmet 2016-04-27

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에서 SQL Server로 전달되는 내용을 정확히 확인할 수 있습니다.


1

일반적으로 이러한 종류의 오류는 DateTime 변환 또는 구문 분석을 수행 할 때 발생합니다. 애플리케이션이 호스팅되는 서버의 캘린더 설정 (주로 시간대 및 간단한 날짜 형식)을 확인하고 위치에 맞는 시간대로 설정되어 있는지 확인합니다. 이것이 문제를 해결하기를 바랍니다.


0

나는 똑같은 것을보고있다. 행 삽입시 오류가 발생하지 않고 업데이트시 발생합니다. 내가 참조하는 테이블에는 두 개의 DateTime 열이 있으며 둘 다 nullable이 아닙니다.

행을 가져오고 즉시 저장하는 시나리오를 얻었습니다 (데이터 변경 없음). 가져 오기는 제대로 작동하지만 업데이트가 실패합니다.

NHibernate 3.3.1.4000을 사용하고 있습니다.


0

NHibernate를 사용하는 경우 nullable 인 적절한 DateTime 속성이 매핑에서 nullable로 설정되어 있는지 확인하십시오.


0

DateTime처럼 Datetime을 nullable로 설정하면? 모델에서는 예외가 발생하지 않습니다. 나는 내 경우에 이와 같은 문제를 해결했다.


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.