Sur SQL Server 2012 et versions ultérieures, vous pouvez utiliser TRY_CONVERT pour vérifier si l'entrée peut être convertie. Si ce n'est pas le cas, une valeur NULL est renvoyée, vous pouvez alors faire un COALESCE pour obtenir la valeur convertie ou la date fixe.
begin
declare @result date
set @result = COALESCE(TRY_CONVERT(date, @date, 111), '2012-01-01')
return @result
end
Vous pouvez également utiliser un TRY CATCH
bloc et renvoyer la date fixe dans le CATCH
bloc, mais il est recommandé d'utiliser TRY_CONVERT afin que SQL Server n'ait pas à gérer une erreur car cela nécessite plus de temps et de ressources.
Une fonction pour ce type de code entraînera plus de surcharge que la simple utilisation de la même logique dans la requête, donc si elle est appelée plusieurs fois par seconde, vous risquez de consommer des ressources importantes en utilisant une fonction pour elle. Je comprends que cela peut être appelé à partir de nombreux morceaux de code, il y a donc un désir d'en faire une fonction au cas où la date par défaut devrait être changée - alors ce n'est pas un changement de code compilé et il suffit de mettre à jour cette fonction.
Si ce code va être exécuté beaucoup, vous devriez considérer d'autres options qui fourniront de meilleures performances qu'une fonction définie par l'utilisateur. Veuillez consulter la réponse de Salomon pour un aperçu de vos options et une explication supplémentaire de la raison pour laquelle vous pouvez choisir l'une plutôt que l'autre.
Par exemple, ce qui suit montre la même logique implémentée en tant que fonction de valeur de table en ligne, qui doit être utilisée avec CROSS APPLY
si elle n'est pas fournie avec une valeur statique, mais fonctionne bien mieux qu'une UDF scalaire:
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
*/