2011-03-21 50 views
2

如何將varchar參數轉換爲datetime,如果轉換失敗,則使用GetDate()作爲默認值? 我試圖把它放在Try/Catch中,但顯然這在UDF中不起作用。它也無法簡單地檢查日期時間是否爲空,因爲它會引發異常('將char數據類型轉換爲導致日期時間值超出範圍的日期時間數據類型'):嘗試/抓住UDF不可能?如何「TryCast」日期時間varchar?

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 
+0

您是否期待任何特定的日期格式?或者它是開放的? 「2010年1月1日」,「12/13/2011」,「2010.02.02」等? – RichardTheKiwi 2011-03-21 11:15:25

+0

udf主要用於excel插件,我可以假裝格式(02.12.2010)。 – 2011-03-21 11:24:00

+0

你可以假裝,但錯誤的DATEFORMAT設置將拋出ISDATE,你可能有''getdate()'' – RichardTheKiwi 2011-03-21 11:46:07

回答

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

看到我的答案。仍然在擴大它 – RichardTheKiwi 2011-03-21 11:21:30

+0

@理查德 - 好點,在'set dateformat dmy'下。 'SELECT CONVERT(DATETIME,'2011.12.13',102),ISDATE('2011.12.13')'返回2011-12-13 00:00:00.000,0',所以在這種情況下不必要的悲觀。如果你期望日期是'ymd'格式,那麼你的日期格式是'dmy'嗎? – 2011-03-21 11:26:59

+0

我希望如此。因爲我在英國系統(dmy)工作,但數據來自一些導入,而ymd是相當常見的。 – RichardTheKiwi 2011-03-21 11:44:08

0

只是檢查時的空

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

'@ StrDeliveryDate'不會爲空,但可能是' - '或'否'或whatelse。 – 2011-03-21 11:26:22

+0

@Tim:好吧,我會刪除我的答案。 – 2011-03-21 22:41:34

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格式日期。

+0

+1看起來應該避免使用'isdate'出現任何問題 – 2011-03-21 11:49:31