Su SQL Server 2012 e versioni successive è possibile utilizzare TRY_CONVERT per verificare se è possibile convertire l'input. In caso contrario, viene restituito un valore NULL, quindi è possibile eseguire una COALESCE per ottenere il valore convertito o la data fissa.
begin
declare @result date
set @result = COALESCE(TRY_CONVERT(date, @date, 111), '2012-01-01')
return @result
end
È inoltre possibile utilizzare un TRY CATCH
blocco e restituire la data fissa nel CATCH
blocco, ma è consigliabile utilizzare TRY_CONVERT in modo che SQL Server non debba gestire un errore poiché richiede più tempo e risorse.
Una funzione per questo tipo di codice comporterà un sovraccarico maggiore del semplice utilizzo della stessa logica nella query, quindi se viene chiamata più volte al secondo, è possibile masticare risorse significative utilizzando una funzione per esso. Capisco che questo può essere chiamato da numerosi pezzi di codice, quindi c'è il desiderio di renderlo una funzione nel caso in cui la data predefinita debba essere cambiata - quindi non si tratta di modifiche al codice compilate e basta aggiornare questa funzione.
Se questo codice verrà eseguito molto, è necessario considerare altre opzioni che forniranno prestazioni migliori rispetto a una funzione definita dall'utente. Perfavore guarda la risposta di Solomon per una panoramica delle tue opzioni e un'ulteriore spiegazione del perché potresti scegliere l'una rispetto all'altra.
Ad esempio, quanto segue mostra la stessa logica implementata come funzione inline con valori di tabella, che deve essere utilizzata CROSS APPLY
se non fornita con un valore statico, ma offre prestazioni molto migliori di un UDF scalare:
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
*/