简体   繁体   English

SQL Server严格从varchar转换为datetime

[英]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 has unexpected format? 我在Sql Server 2005中将varchar转换为datetime。如果提供的varchar具有意外格式,是否可以强制Sql Server失败?

Example: 例:

select convert(datetime, '01-2010-02', 103) 

Expected result: query fails because 103 means dd/mm/yyyy (see msdn ). 预期结果:查询失败,因为103表示dd / mm / yyyy(请参阅msdn )。

Actual result: 2010-02-01 00:00:00.000 实际结果: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). 如果以yyyy-mm-dd格式提供varchar,则由于以提供的格式(dd / mm / yyyy)的日/月顺序,Sql Server将把mm视为日,将dd视为月。

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. 恐怕您必须使用CLR函数并利用DateTime.TryParseExact方法。 Not an elegant solution but could work. 这不是一个优雅的解决方案,但可以工作。

Whenever SQL Server sees a clear candidate for Year, it will always be used as Year. 每当SQL Server看到Year的明确候选者时,它将始终用作Year。

The remaining DM parts are determined from the order within the DMY setting or the convert format. DM剩余部分由DMY设置或转换格式中的顺序确定。 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 第2和第3个明确地将Year放在前面, 没关系


EDIT 编辑

Books Online has this to say http://msdn.microsoft.com/en-us/library/ms180878.aspx#StringLiteralDateandTimeFormats 联机丛书具有这样的说法: http://msdn.microsoft.com/zh-cn/library/ms180878.aspx#StringLiteralDateandTimeFormats

There are quite a few exceptions to SET DATEFORMAT, which plays a role regardless of the 3rd param to CONVERT. SET DATEFORMAT有很多例外,无论转换的第三个参数如何,SET DATEFORMAT都会发挥作用。

  • The SET DATEFORMAT session setting does not apply to all-numeric date entries SET DATEFORMAT会话设置不适用于全数字日期输入
  • This [ISO 8601] format is not affected by the SET DATEFORMAT, SET LANGUAGE, of login default language settings. 此[ISO 8601]格式不受登录默认语言设置的SET DATEFORMAT,SET LANGUAGE的影响。
  • The SET DATEFORMAT session setting is not applied when you specify the month in alphabetical form. 当您以字母形式指定月份时,将不应用SET DATEFORMAT会话设置。
  • etc 等等

To specifically validate dd/mm/yyyy, use the below instead 要专门验证dd / mm / yyyy,请改用以下内容

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

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM