使用T-SQL DATEFROMPARTS返回NULL而不是throw错误

时间:2015-03-12 20:57:35

标签: sql sql-server tsql

我经常以某些整数组合或单个8位整数的形式收到日期。为了将它们转换为可用的日期,我尝试了DATEFROMPARTS函数,但是当日期是无意义的时,它会在首选NULL时抛出错误。

我希望找到一个行为类似于TRY_PARSE的函数,它接受整数并为无效日期返回NULL而不是错误但不需要字符串转换,因为我想在PERSISTED计算字段中使用它。最后,我决定在转换之前测试整数。

CASE WHEN @year BETWEEN 1 AND 9999 AND (@month BETWEEN 1 AND 12 AND @day BETWEEN 1 AND 28
       OR @month IN(1, 3, 5, 7, 8, 10, 12) AND @day BETWEEN 1 AND 31
       OR @month IN(4, 6, 9, 11) AND @day BETWEEN 1 AND 30
       OR @month = 2 AND @day BETWEEN 1 and CASE WHEN NOT @year % 4 = 0 THEN 28 WHEN NOT @year % 100 = 0 THEN 29 WHEN NOT @year % 400 = 0 THEN 28 ELSE 29 END)
     THEN DATEFROMPARTS(@year, @month, @day) END

这给出了所有1000万个相关整数输入的日期或NULL(年份从0到9999,月份从0到99,白天从0到99)我假设结果是正确的但我还没有完成测试。是否有更好的方法可以将整数输入安全地转换为持久计算字段的日期(因此不允许字符串转换),这不会引发我没有找到的错误?

1 个答案:

答案 0 :(得分:0)

我不确定我是否理解你,但这可能有所帮助:

DECLARE @year VARCHAR(100)= '1993';
DECLARE @month VARCHAR(100)= '12';
DECLARE @day VARCHAR(100)= '01';


SELECT CASE 
WHEN  ISNUMERIC(@year) = 0 OR  ISNUMERIC(@month) = 0 OR  ISNUMERIC(@day) = 0 THEN NULL
WHEN @year BETWEEN 1 AND 9999 AND (@month BETWEEN 1 AND 12 AND @day BETWEEN 1 AND 28
       OR @month IN(1, 3, 5, 7, 8, 10, 12) AND @day BETWEEN 1 AND 31
       OR @month IN(4, 6, 9, 11) AND @day BETWEEN 1 AND 30
       OR @month = 2 AND @day BETWEEN 1 and CASE WHEN NOT @year % 4 = 0 THEN 28 WHEN NOT @year % 100 = 0 THEN 29 WHEN NOT @year % 400 = 0 THEN 28 ELSE 29 END)
     THEN DATEFROMPARTS(@year, @month, @day) END;

输出:

  

1993-12-01

DECLARE @year VARCHAR(100)= '1993';
DECLARE @month VARCHAR(100)= 'Jan';
DECLARE @day VARCHAR(100)= '01';


SELECT CASE 
WHEN  ISNUMERIC(@year) = 0 OR  ISNUMERIC(@month) = 0 OR  ISNUMERIC(@day) = 0 THEN NULL
WHEN @year BETWEEN 1 AND 9999 AND (@month BETWEEN 1 AND 12 AND @day BETWEEN 1 AND 28
       OR @month IN(1, 3, 5, 7, 8, 10, 12) AND @day BETWEEN 1 AND 31
       OR @month IN(4, 6, 9, 11) AND @day BETWEEN 1 AND 30
       OR @month = 2 AND @day BETWEEN 1 and CASE WHEN NOT @year % 4 = 0 THEN 28 WHEN NOT @year % 100 = 0 THEN 29 WHEN NOT @year % 400 = 0 THEN 28 ELSE 29 END)
     THEN DATEFROMPARTS(@year, @month, @day) END;

输出:

  

NULL