Sql Server严格从varchar转换为datetime

时间:2011-02-24 17:50:45

标签: sql-server sql-server-2005 datetime strict

我在sql Server 2005中将varchar转换为datetime。如果varchar有意外的格式,我可以强制Sql Server失败吗?

示例:

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

预期结果:查询失败,因为103表示dd / mm / yyyy(参见msdn)。

实际结果:2010-02-01 00:00:00.000

请求执行的主要目的是日期和月份的顺序。如果以yyyy-mm-dd格式提供varchar,则Sql Server会将mm视为day,dd视为月份,因为提供的格式为日/月顺序(dd / mm / yyyy)。

注意:我可以编写自定义函数来手动处理这种情况。但我希望这样的企业数据库已经可以严格使用数据了。

3 个答案:

答案 0 :(得分:0)

我担心您必须使用CLR Function并利用DateTime.TryParseExact方法。不是一个优雅的解决方案,但可以工作。

答案 1 :(得分:0)

每当SQL Server看到Year的明确候选者时,它将始终用作Year。

剩余的DM部分是根据DMY设置或转换格式中的顺序确定的。如果不是这样,那么非常简单的转换就会崩溃。

实施例

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')

输出

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

第二个和第三个明确地将年份放在前面,这是 ok

<小时/>

修改

联机丛书可以说http://msdn.microsoft.com/en-us/library/ms180878.aspx#StringLiteralDateandTimeFormats

SET DATEFORMAT有很多例外,它与CONVERT的第3个参数无关。

  • SET DATEFORMAT会话设置不适用于所有数字日期条目
  • 此[ISO 8601]格式不受登录默认语言设置的SET DATEFORMAT,SET LANGUAGE的影响。
  • 当您按字母顺序指定月份时,不会应用SET DATEFORMAT会话设置。

要专门验证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

答案 2 :(得分:0)

您可以将日期与转换为日期时间进行比较,然后再返回。我不确定是否有任何陷阱这样做但我的有限测试没有发现任何。

if @StrDate = convert(varchar(10), convert(datetime, @StrDate, 103) ,103)