我正在使用当前将日期存储为varchars的SQL Server 2005数据库表。这超出了我的控制范围。为了便于报告,我想创建一个将这些varchar日期转换为datetime字段的视图。
除了偶尔输入错误外,varchar日期的大部分格式都已格式化。
DateString
----------
2001/01/02 -- most of the fields
2002/0601 -- typo, missing slash between month and day
2004/02/30 -- typo, no 30th of February
由于日期已经过格式化,我使用cast
功能将其转换为datetime
。
cast(DateString as datetime)
问题是当cast
函数遇到错误的日期时,查询会以错误结束。
是否有办法将函数包装在try...catch
块中?我认为可以wrap an entire query in a try...catch
block,但完整查询必须完成多次转换,任何组合都可能有输入错误。
答案 0 :(得分:1)
如果逻辑很复杂(例如,您想要尝试纠正错误,例如缺少斜杠,或者在第30个FEB的情况下最近的一天),那么一个选项是创建一个包含日期的用户定义函数解析其中的逻辑(字符串到日期)逻辑,完成错误处理(例如,在转换之前的情景检查)。然后在查询中,调用用户定义的函数。
概要:
CREATE FUNCTION udf_ParseDateString
(
@DateString nvarchar(20)
)
RETURNS DateTime
AS
BEGIN
DECLARE @returnDateTime datetime
-- Do any string checking, and date casting here
-- @DateString -> @returnDateTime
return @returnDateTime
END
请注意won't be able to use TRY-CATCH in a UDF。
或者,如果您的逻辑很简单,则可以使用强制转换,as suggested here。
SET DATEFORMAT ymd;
-- Incorporate this into query.
SELECT CASE WHEN ISDATE(@yourParameter) = 1
THEN CAST(@yourParameter AS DATETIME)
ELSE YourDefaultValue
END
如果您使用的是SQL Server 2012,则可以使用TRY_CAST
函数。
答案 1 :(得分:1)
我会使用内置的ISDATE()
函数。然后,您可以在CASE
语句中编写SELECT
语句,以返回已解析的日期或null或其他结果。或者,您可以将其直接放在WHERE子句中,只返回有效日期的那些行。
ISDATE()
列表中SELECT
功能的可能解决方案可能如下所示:
select case
when ISDATE(DateString) = 1 then cast(DateString as datetime)
else null --or other error result
end as CastedDate
from TableName