W SQL Server 2012 i późniejszych można użyć TRY_CONVERT, aby sprawdzić, czy dane wejściowe można przekonwertować. Jeśli nie jest to możliwe, zwracana jest wartość NULL, a następnie możesz wykonać WSPÓŁPRACĘ, aby uzyskać wartość przeliczoną lub ustaloną datę.
begin
declare @result date
set @result = COALESCE(TRY_CONVERT(date, @date, 111), '2012-01-01')
return @result
end
Możesz także użyć TRY CATCH
bloku i zwrócić ustaloną datę w CATCH
bloku, ale najlepszym rozwiązaniem jest użycie TRY_CONVERT, aby SQL Server nie musiał obsługiwać błędu, ponieważ wymaga to więcej czasu i zasobów.
Funkcja dla tego typu kodu spowoduje większe obciążenie niż zwykłe użycie tej samej logiki w zapytaniu, więc jeśli jest wywoływana wiele razy na sekundę, możesz przeżuć znaczny zasób, używając dla niego funkcji. Rozumiem, że może to być wywołane z wielu fragmentów kodu, więc istnieje potrzeba, aby włączyć tę funkcję na wypadek, gdyby konieczna była zmiana domyślnej daty - wtedy nie ma zmian w skompilowanym kodzie i wystarczy zaktualizować tę funkcję.
Jeśli ten kod będzie często uruchamiany, należy rozważyć inne opcje, które zapewnią lepszą wydajność niż funkcja zdefiniowana przez użytkownika. Zapoznaj się z odpowiedzią Solomona, aby uzyskać przegląd dostępnych opcji i dodatkowe wyjaśnienie, dlaczego możesz wybrać jedną z nich.
Na przykład poniżej pokazano tę samą logikę zaimplementowaną jako wbudowana funkcja o wartościach w tabeli, która musi być używana z, CROSS APPLY
jeśli nie jest dostarczana z wartością statyczną, ale działa znacznie lepiej niż skalarny 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
*/