저는 제가 작성한이 코드를 사용해 왔으며 가장 명확하지 않은 방식으로 작동하고 있습니다. 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에 대한 첫 번째 삽입에서 작동했지만 거기서부터 실패했다는 것입니다. 무슨 일이 일어나고 있는지 아이디어가 있습니까?
답변
DateTime
C #에서 A 는 참조 형식이 아닌 값 형식이므로 null 일 수 없습니다. 그러나 DateTime.MinValue
Sql 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 데이터 유형을 사용하는 것이 좋습니다.DateTime
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");
답변
많은 DB 관련 오류 후 SQL 최소 / 최대 날짜에 대해 다음을 사용하면 매우 잘 작동합니다.
DateTime rngMin = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue;
DateTime rngMax = (DateTime)System.Data.SqlTypes.SqlDateTime.MaxValue;
답변
.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와 비교하는 것입니다. 가치 .
답변
두 열에 대한 코드는 괜찮아 보입니다. 해당 매핑 클래스에서 다른 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 인지 확인하십시오.
답변
이 오류는 DateTime 유형의 변수 를 null 로 설정하려는 경우 발생합니다 . 변수를 nullable로 선언하십시오. 즉, DateTime? . 이것은 문제를 해결할 것입니다.
답변
때로는 적은 코드를 작성하기 위해 필드의 기본값을 GETDATE()
또는 로 설정하여 삽입시 SQL 서버가 날짜, 시간 및 ID와 같은 필드를 설정하도록하는 데 사용됩니다 NEWID()
.
이러한 경우 엔터티 클래스에있는 해당 필드의 자동 생성 값 속성을 true로 설정해야합니다.
이렇게하면 코드에서 값을 설정할 필요가 없으며 (에너지 소비 방지 !!!) 예외를 볼 수 없습니다.
답변
확장 방법 사용
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();