接收字符输入并返回日期格式的函数(输入不正确)

Pan*_*tea 10 sql-server t-sql functions

我需要编写一个函数来接收字符串字符并返回日期格式。例如输入是 20120101,我需要这个 2012-01-01。问题是可能存在一些不正确的输入,例如“2012ABCD”。在这种情况下,我希望函数返回一个固定日期,例如 2020-01-01。到目前为止我写的是:

Create Function ReturnDate
(@date varchar(8))

Returns date

  as

    begin
       declare @result date

          set @result = (select convert(date , @date,111))
                if(@@ROWCOUNT>0) return @result
                 else return '2020-01-01'
       return @result
    end
Run Code Online (Sandbox Code Playgroud)

这不起作用,我只是不知道如何处理第二部分(当输入不正确时)。

Ton*_*kle 9

在 SQL Server 2012 及更高版本上,您可以使用TRY_CONVERT检查输入是否可以转换。如果不能,则返回 NULL 值,然后您可以执行 COALESCE 以获取转换后的值或固定日期。

begin
   declare @result date
   set @result = COALESCE(TRY_CONVERT(date, @date, 111), '2012-01-01')
   return @result
end
Run Code Online (Sandbox Code Playgroud)

您还可以使用TRY CATCH块并返回块中的固定日期CATCH,但最佳做法是使用 TRY_CONVERT,这样 SQL Server 就不必处理错误,因为这需要更多的时间和资源。

与简单地在查询中使用相同的逻辑相比,此类代码的函数会产生更多的开销,因此如果每秒调用多次,您可能会通过使用函数来消耗大量资源。我知道这可能会从大量代码中调用,因此希望在需要更改默认日期的情况下使其成为一个函数——然后它没有编译代码更改,只需更新此函数。

如果此代码要运行很多次,您应该考虑其他选项,这些选项将提供比用户定义的函数更好的性能。请参阅Solomon 的回答,以了解您的选择的概述以及您可能会选择其中一个的原因的进一步解释。

例如,下面显示了作为内联表值函数实现的相同逻辑,它需要与CROSS APPLYif 未提供静态值一起使用,但性能比标量 UDF 好得多:

USE [tempdb];

GO
CREATE
OR ALTER -- comment out if using pre-SQL Server 2016 SP1
FUNCTION dbo.ReturnDate (@Date VARCHAR(8))
RETURNS TABLE
AS RETURN
  SELECT ISNULL(TRY_CONVERT(DATE, @Date, 111), '2020-01-01') AS [TheDate];
GO


SELECT *
FROM   (VALUES (1, '20120101'), (2, '2012ABCD')) tab(ID, Input)
CROSS APPLY dbo.ReturnDate(tab.[Input]) dt
/*
ID    Input       TheDate
1     20120101    2012-01-01
2     2012ABCD    2020-01-01
*/
Run Code Online (Sandbox Code Playgroud)

  • 但我只会在查询中使用 TRY_CONVERT 并放弃使用低效标量 UDF 的整个想法...... (6认同)
  • 托尼:我没有投反对票,但我当然同意有人不应该在没有在评论中提供推理的情况下投反对票,或者对包含其推理的现有评论投反对票。也就是说:**1)** 在 T-SQL 中没有 `FINALLY` 块(我想你的意思是 `CATCH`)。**2)** 您可能应该提到 `TRY_CONVERT` 始于 2012 年(有些人被困在 SQL Server 2012 之前)。**3)** 您考虑过内联 TVF 吗?那些没有与标量 UDF 相同的性能问题。 (3认同)
  • 我并不真正关心代表点数,所以我不是因为失去这些点数而这么说,但是社区不会从对明显正确的答案投反对票中受益。不要投反对票,而是写一个答案,编辑我的答案,或者对需要更改的内容发表评论。OP 要求提供一个功能,我意识到这可能不是最好的解决方案,但它是要求的解决方案。 (2认同)