接收字符输入和返回日期格式的函数(输入错误)


9

我需要编写一个函数来接收字符串字符并返回日期格式。例如输入是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

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


1
我可能建议您阅读“使用Transact-SQL查询数据”。如果您将要进行大量的SQL编程,那么这本书将教您如何编写类似代码的基础知识。 amazon.com/Exam-70-761-Querying-Data-Transact-SQL-ebook/dp/...
托尼·欣克尔

1
是否要严格解析yyyymmdd格式?
Dan Guzman

Answers:


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

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

与仅在查询中简单地使用相同的逻辑相比,用于这种类型的代码的函数会产生更多的开销,因此,如果每秒调用多次该函数,则可能会因为使用函数而浪费大量资源。我知道可以从许多代码中调用此函数,因此希望在需要更改默认日期的情况下使其成为一个函数-这样就无需更改已编译的代码,只需更新此函数即可。

如果要大量运行此代码,则应考虑其他选项,这些选项将提供比用户定义的函数更好的性能。请参阅所罗门的答案,以大致了解您的选择,并进一步解释为什么您可能会选择其中一个。

例如,下面显示了与内联表值函数实现的逻辑相同的逻辑,CROSS APPLY如果未提供静态值,则需要与之一起使用,但是其性能要比标量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
*/

6
但是我只是在查询中使用TRY_CONVERT,而放弃了为此使用效率低下的标量UDF的整个想法……
Aaron Bertrand

2
我并不真的在乎代表点,所以我并不是说由于失去这样的代表而已,但社区不会从降低明显正确答案的投票中受益。不用投票,而是写一个答案,编辑我的答案或对需要更改的内容发表评论。OP要求一个功能,我意识到这可能不是最佳解决方案,但它是所要求的解决方案。
Tony Hinkle

3
托尼(Tony):我没有拒绝投票,但我当然同意,在不提供评论中的推理或不对包含其推理的现有评论进行投票的情况下,不应拒绝某人的投票。就是说:1)FINALLY T-SQL中没有块(我想你的意思是CATCH)。2)您可能应该提到TRY_CONVERT从2012年开始的代码(有些人在SQL Server 2012之前陷入困境)。3)您是否考虑过Inline TVF?这些不存在与标量UDF相同的性能问题。
所罗门·鲁兹基

1
@TonyHinkle感谢您进行这些编辑,并感谢对我的SO回答:)。不过,我不确定有多少读者能够从看到UDF逻辑并阅读到内置TVF会更好地飞跃到成功实施iTVF。因此,我继续将其添加到答案的末尾。
所罗门·鲁兹基

1
@SolomonRutzky谢谢。我不是真正的SQL开发人员,因此仍然无法解决。也许我不应该回答这样的问题,但这是一个巨大的学习机会。
托尼·欣克尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.