在UDF中尝试/捕获不可能吗?如何“tryCast”varchar到datetime?

时间:2011-03-21 11:10:34

标签: sql sql-server-2005 tsql

如何将varchar参数转换为datetime,如果强制转换失败则使用GetDate()作为默认值? 我试图把它放在Try / Catch中,但显然它不适用于UDF。它也不能简单地检查日期时间是否为空,因为它会抛出异常('将char数据类型转换为日期时间数据类型会导致超出范围的日期时间值& #39):

CREATE FUNCTION [dbo].[getRZUInfo]
(
    @IMEI varchar(20),
    @StrDeliveryDate varchar(20)
)
RETURNS VARCHAR(8000)
AS
BEGIN
    DECLARE @Info VARCHAR(8000) 
    DECLARE @DeliveryDate datetime;
    SET @DeliveryDate = Convert(datetime,@StrDeliveryDate,102);
    IF @DeliveryDate IS NULL
        SET @DeliveryDate=GetDate();
    SELECT   @Info = COALESCE(@Info + '|', '') + 'TAT_B2B: ' + Convert(varchar,tabData.TAT_B2B) + ', AC' + Convert(varchar,tabData.fimaxActionCode) + ', Diff: ' + Convert(varchar,DateDiff(day,tabData.Received_date,@DeliveryDate))
        FROM   tabData
    WHERE     (SSN_Number = @IMEI) AND (Received_Date >= DATEADD(month, -3, @DeliveryDate))
    ORDER BY SSN_Number,Received_Date DESC
    return @Info
END

3 个答案:

答案 0 :(得分:6)

SET @DeliveryDate = CASE
                      WHEN Isdate(@StrDeliveryDate) = 1 THEN
                      CONVERT(DATETIME, @StrDeliveryDate, 102)
                      ELSE Getdate()
                    END  

答案 1 :(得分:2)

IsDate的一个常见缺陷是它无法接受CAST / CONVERT可以使用的日期格式说明符。

见:

set dateformat dmy
declare @StrDeliveryDate varchar(20) set @StrDeliveryDate = '2011.12.13'
select CASE
 WHEN Isdate(@StrDeliveryDate) = 1 THEN
 CONVERT(DATETIME, @StrDeliveryDate, 102)
 ELSE Getdate()
 END 

output: 2011-03-21 22:19:54.683

这是一个更好的功能,专门用于测试102格式的日期。实际上102更容易,这足够灵活,可以拿起yy / yyyy,m / mm,d / dd。

create function dbo.Is102Date(@any varchar(50))
-- 102 = yyyy.mm.dd
returns bit as begin
set @any = ltrim(rtrim(@any))
declare @theyear varchar(10)
set @TheYear = case
       when @any like '%[^0-9.]%' then null
       when @any like '[0-9][0-9].%[0-9].%[0-9]' then
           case when LEFT(@any,2) >=50
           then '19'+LEFT(@any,2)
           else '20'+LEFT(@any,2)
           end
       when @any like '[0-9][0-9][0-9][0-9].%[0-9].%[0-9]' then
           LEFT(@any,4)
       end
declare @YYYYMMDDToTest varchar(50)
set @YYYYMMDDToTest = case
       when @TheYear is not null then
           @TheYear
           + -- month
           SUBSTRING(@any, charindex('.',@any) +1,
           charindex('.',@any,charindex('.',@any)+1)-
           charindex('.',@any)-1)
           + -- day
           right(@any,charindex('.',reverse(@any))-1)
       end
return ISDate(@YYYYMMDDToTest)
end
GO

使用它代替ISDATE来测试varchar中的102格式日期。

答案 2 :(得分:0)

只检查Null

IF @StrDeliveryDate IS NULL
    SET @DeliveryDate = GetDate();
ELSE
    SET @DeliveryDate = Convert(datetime, @StrDeliveryDate, 102);