Asynchronous
Asynchronous

Reputation: 3977

Creating User Define Function to Convert Dates in SQL Server

I know how to convert to date in SQL Server (T-SQL) but how do I create a UDF so that I can call it each time in my code?

Example 1: The below code will format this 20120428 to 04/28/2012

SELECT CONVERT(CHAR(10), CONVERT(DATE, TEST_DATE), 101) AS MY_DATE
FROM
MEMBER
WHERE ISDATE(TEST_DATE) <> 0

Example 2: The below code will format this 20120428 to 2012-04-28

SELECT CONVERT(DATE, TEST_DATE) AS MY_DATE
FROM
MEMBER
WHERE ISDATE(TEST_DATE) <> 0

Thank for the input!

Guy

Upvotes: 4

Views: 10410

Answers (1)

Aaron Bertrand
Aaron Bertrand

Reputation: 280479

For the second example you can do this:

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

But a more flexible approach might be:

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);

Results:

----------  ----------  ----------  ----------
2012-04-28  04/28/2012  28/04/2012  2012-04-28

If you don't want to continue filtering out bad non-dates from your source table (keeping the ISDATE() in the WHERE clause should prevent the function from having to deal with those rows), you can change the function this way to avoid errors, if NULL is okay as a substitute:

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

In SQL Server 2012, you can do this instead, which does the same thing without having to write your own CASE:

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

(In fact in SQL Server 2012 you can also use FORMAT() so that you don't have to memorize the style numbers, but since I don't know what version you're using I'll leave that for another day.)

All that said, other than saving a few keystrokes in your queries, this encapsulation is actually going to make your queries perform worse (depending on where they are used). For simple conversions like this it is much better to just perform them inline in most cases.

Upvotes: 6

Related Questions