Sql Server strict convert from varchar to datetime
I'm converting varchar to datetime in Sql Server 2005. Can I force Sql Server to fail if provided varchar h开发者_开发知识库as unexpected format?
Example:
select convert(datetime, '01-2010-02', 103)
Expected result: query fails because 103 means dd/mm/yyyy (see msdn).
Actual result: 2010-02-01 00:00:00.000
Main purpose of requested enforcement is order of day and month. If varchar is provided in format yyyy-mm-dd then Sql Server will treat mm as day and dd as month because of day/month order in provided format (dd/mm/yyyy).
Note: I can write custom function to manually handle this case. But I hope such enterprise DB already can work strictly with data.
I am afraid you have to use CLR Function and take advantage of using DateTime.TryParseExact method. Not an elegant solution but could work.
You can compare the date with a convert to datetime and back again. I don't know for sure if there are any pitfalls doing like this but my limited tests has not discovered any.
if @StrDate = convert(varchar(10), convert(datetime, @StrDate, 103) ,103)
Whenever SQL Server sees a clear candidate for Year, it will always be used as Year.
The remaining DM parts are determined from the order within the DMY setting or the convert format. If that weren't true, then very simple conversions will fall apart.
Example
set dateformat dmy
select 1 a,CONVERT(datetime, '1-2-3') b
union all
select 2,CONVERT(datetime, '2001-2-3')
union all
select 3,CONVERT(datetime, '2001-3-2')
Output
a b
----------- -----------------------
1 2003-02-01 00:00:00.000
2 2001-03-02 00:00:00.000
3 2001-02-03 00:00:00.000
The 2nd and 3rd explicitly put the Year in front, and that is ok
EDIT
Books Online has this to say http://msdn.microsoft.com/en-us/library/ms180878.aspx#StringLiteralDateandTimeFormats
There are quite a few exceptions to SET DATEFORMAT, which plays a role regardless of the 3rd param to CONVERT.
- The SET DATEFORMAT session setting does not apply to all-numeric date entries
- This [ISO 8601] format is not affected by the SET DATEFORMAT, SET LANGUAGE, of login default language settings.
- The SET DATEFORMAT session setting is not applied when you specify the month in alphabetical form.
- etc
To specifically validate dd/mm/yyyy, use the below instead
set dateformat dmy
declare @input varchar(10) set @input = '12-2010-01'
-- convert allows the date through
select convert(datetime, @input, 103) -- 2010-01-12 00:00:00.000
-- the case below returns 0 { = invalid date }
-- this uses 8-digit format which is always interpreted YYYYMMDD regardless
-- of language or dateformat settings
select case
when @input not like '__/__/____' then 0
else isdate(right(@input,4)+right(left(@input,5),2)+left(@input,2))
end
精彩评论