在SQL Server中创建用户定义函数以转换日期

在SQL Server中创建用户定义函数以转换日期,sql,sql-server,tsql,Sql,Sql Server,Tsql,我知道如何在SQL Server(T-SQL)中转换为日期,但如何创建UDF以便每次在代码中调用它 示例1:以下代码将此20120428格式化为2012年4月28日 SELECT CONVERT(CHAR(10), CONVERT(DATE, TEST_DATE), 101) AS MY_DATE FROM MEMBER WHERE ISDATE(TEST_DATE) <> 0 选择CONVERT(字符(10)、CONVERT(日期、测试日期)、101)作为我的日期 从…起 成员

我知道如何在SQL Server(T-SQL)中转换为日期,但如何创建UDF以便每次在代码中调用它

示例1:以下代码将此20120428格式化为2012年4月28日

SELECT CONVERT(CHAR(10), CONVERT(DATE, TEST_DATE), 101) AS MY_DATE
FROM
MEMBER
WHERE ISDATE(TEST_DATE) <> 0
选择CONVERT(字符(10)、CONVERT(日期、测试日期)、101)作为我的日期
从…起
成员
其中ISDATE(测试日期)0
示例2:以下代码将此20120428格式化为2012-04-28

SELECT CONVERT(DATE, TEST_DATE) AS MY_DATE
FROM
MEMBER
WHERE ISDATE(TEST_DATE) <> 0
选择转换(日期、测试日期)作为我的日期
从…起
成员
其中ISDATE(测试日期)0
谢谢你的意见


Guy

对于第二个示例,您可以这样做:

CREATE FUNCTION dbo.ConvertDate(@d CHAR(10))
RETURNS DATE
AS
BEGIN
    RETURN (SELECT CONVERT(DATE, @d));
END
GO
但更灵活的方法可能是:

CREATE FUNCTION dbo.ConvertRegional
(
  @d CHAR(10),
  @style TINYINT
)
RETURNS CHAR(10)
AS
BEGIN
    RETURN (SELECT CONVERT(CHAR(10), CONVERT(DATE, @d), @style));
END
GO

DECLARE @d CHAR(10);
SELECT @d = '20120428';

SELECT 
 dbo.ConvertDate(@d),
 dbo.ConvertRegional(@d, 101),
 dbo.ConvertRegional(@d, 103),
 dbo.ConvertRegional(@d, 120);
结果:

----------  ----------  ----------  ----------
2012-04-28  04/28/2012  28/04/2012  2012-04-28
如果不想继续从源表中筛选出错误的非日期(将ISDATE()保留在WHERE子句中应该可以防止函数必须处理这些行),可以通过这种方式更改函数以避免错误,如果可以使用NULL替代:

CREATE FUNCTION dbo.ConvertRegional
(
  @d CHAR(10),
  @style TINYINT
)
RETURNS CHAR(10)
AS
BEGIN
    RETURN (SELECT CASE WHEN ISDATE(@d) = 1 THEN
      CONVERT(CHAR(10), CONVERT(DATE, @d), @style)
      END);
END
GO
在SQL Server 2012中,您可以这样做,而不必编写自己的案例:

CREATE FUNCTION dbo.ConvertRegional
(
  @d CHAR(10),
  @style TINYINT
)
RETURNS CHAR(10)
AS
BEGIN
    RETURN (SELECT CONVERT(CHAR(10), TRY_CONVERT(DATE, @d), @style));
END
GO
(事实上,在SQL Server 2012中,您也可以使用FORMAT(),这样您就不必记住样式编号,但因为我不知道您使用的是什么版本,所以我将把它留到另一天。)


综上所述,除了在查询中保存一些击键之外,这种封装实际上会使查询的性能更差(取决于它们的使用位置)。对于像这样的简单转换,在大多数情况下,最好只内联执行它们。

实际上,您的第一个示例使用103,这导致2012年4月28日而不是2012年4月28日。作为补充说明,如果您使用的是SQL Server 2012之前的版本,则在select子句之前可能会计算筛选子句,也可能不会计算筛选子句。请看@AaronBertrand对我的感谢的精彩回复,我已经修改了原始帖子中的代码,以展示我如何使用ISDATE过滤糟糕的日期。非常感谢!这是一个具有完美灵活性的好例子。再次感谢!家伙