문자 입력을 받고 날짜 형식을 반환하는 기능 (잘못된 입력)


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/…
Tony Hinkle

1
yyyymmdd형식에 대한 엄격한 구문 분석을 원하십니까 ?
Dan Guzman

답변:


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있지만 SQL Server에서 더 많은 시간과 리소스가 필요하므로 오류를 처리하지 않도록 TRY_CONVERT를 사용하는 것이 가장 좋습니다.

이 유형의 코드에 대한 함수는 쿼리에서 동일한 논리를 사용하는 것보다 더 많은 오버 헤드를 발생 시키므로 매초마다 여러 번 호출되는 경우 함수를 사용하여 중요한 리소스를 씹을 수 있습니다. 나는 이것이 많은 코드 조각에서 호출 될 수 있다는 것을 이해하므로 기본 날짜를 변경해야 할 경우에 함수로 만들고 싶습니다. 그런 다음 컴파일 된 코드가 변경되지 않고이 함수를 업데이트하십시오.

이 코드가 많이 실행될 경우 사용자 정의 함수보다 더 나은 성능을 제공하는 다른 옵션을 고려해야합니다. 선택 사항 에 대한 개요와 왜 다른 것을 선택할 수 있는지에 대한 자세한 설명 은 Solomon의 답변 을 참조하십시오 .

예를 들어, 다음은 인라인 테이블 반환 함수로 구현 된 것과 동일한 논리를 보여줍니다.이 함수 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
토니 : 나는 투표하지 않았지만, 어떤 사람은 의견에 추론을 제시하거나 자신의 추론을 포함하는 기존 의견을 투표하지 않으면 서 투표하지 말아야한다는 것에 확실히 동의합니다. 그건 말했다 : 1) 전혀 없다 FINALLYT-SQL (난 당신이 의미하는 생각에서 블록 CATCH). 2)TRY_CONVERT 2012 년에 시작된 것을 언급해야 할 것입니다 (일부 사람들은 SQL Server 2012 이전 버전에 갇혀 있음). 3) 인라인 TVF를 고려 했습니까? 스칼라 UDF와 동일한 성능 문제는 없습니다.
Solomon Rutzky

1
@TonyHinkle 편집 해주셔서 감사합니다. 내 답변 :). 그럼에도 불구하고 UDF 논리를보고 iTVF를 성공적으로 구현하기 위해 인라인 TVF가 더 나을 것이라는 점에서 도약 할 수있는 독자가 얼마나 될지 잘 모르겠습니다. 그래서 나는 계속해서 당신의 대답 끝에 그것을 추가했습니다.
Solomon Rutzky

1
@SolomonRutzky 감사합니다. 나는 실제로 SQL 개발자가 아니므로 여전히 내 머리 위에 있습니다. 어쩌면 나는 이런 식으로 대답해서는 안되지만 엄청난 학습 기회입니다.
Tony Hinkle
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.