问题
I recently started changing queries to use TRY_PARSE() but I run into a problem when the resulting date is before the year 1753. For example:
SELECT TRY_PARSE('01-Jan-0001' AS datetime)
Results in a .NET error:
Msg 6521, Level 16, State 1, Line 1
A .NET Framework error occurred during statement execution:
System.Data.SqlTypes.SqlTypeException: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
System.Data.SqlTypes.SqlTypeException:
at System.Data.SqlTypes.SqlDateTime.FromTimeSpan(TimeSpan value)
at System.Data.SqlTypes.SqlDateTime.FromDateTime(DateTime value)
at System.Data.SqlServer.Internal.CXVariantBase.DateTimeToSSDate(DateTime dt)
My guess is SQL is just running a direct .NET DateTime.TryParse() and converting straight to SqlDateTime without checking and returning NULL in such instances (as I'd expect the behavior to be). I'd check myself but the catch 22 here is how can you check the validity of the date before parsing when you need to parse to check the validity?
.
回答1:
Use DateTime2 instead of DateTime
SELECT TRY_PARSE('01-Jan-0001' AS datetime2)
SELECT TRY_CONVERT(datetime2, '01-Jan-0001')
And one more thing
Use TRY_CONVERT instead of TRY_PARSE:
TRY_PARSE: Returns the result of the expression, translated to the requested data type, or null if the cast fails.
TRY_CONVERT: Returns a value cast to the specified data type if the cast succeeds; otherwise, returns null.
SELECT TRY_CONVERT(datetime2, '12/31/2010') AS Result;
回答2:
To avoid overflow you just need to change to DATETIME2 datatype. Below is date ranges of two Date datatypes.
DATETIME Date range: January 1, 1753, through December 31, 9999
http://msdn.microsoft.com/en-us/library/ms187819.aspx
DATETIME2 Date range: 0001-01-01 through 9999-12-31
http://msdn.microsoft.com/en-us/library/bb677335.aspx
回答3:
If you don't need the culture parameter of TRY_PARSE you could use TRY_CONVERT instead.
SELECT TRY_CONVERT(datetime, '01-Jan-0001')
来源:https://stackoverflow.com/questions/21255077/resolving-try-parse-overflow-with-datetime-in-sql-server-2012-must-be-between