开发者

Sql Server strict convert from varchar to datetime

开发者 https://www.devze.com 2023-02-13 01:16 出处:网络
I\'m converting varchar to datetime in Sql Server 2005. Can I force Sql Server to fail if provided varchar h开发者_开发知识库as unexpected format?

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
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号