Unter SQL Server 2012 und höher können Sie mit TRY_CONVERT prüfen, ob die Eingabe konvertiert werden kann. Wenn dies nicht möglich ist, wird ein NULL-Wert zurückgegeben. Anschließend können Sie eine COALESCE ausführen, um entweder den konvertierten Wert oder das feste Datum abzurufen.
begin
declare @result date
set @result = COALESCE(TRY_CONVERT(date, @date, 111), '2012-01-01')
return @result
end
Sie können auch einen TRY CATCH
Block verwenden und das feste Datum im CATCH
Block zurückgeben. Es wird jedoch empfohlen, TRY_CONVERT zu verwenden, damit SQL Server keinen Fehler behandeln muss, da dies mehr Zeit und Ressourcen erfordert.
Eine Funktion für diesen Codetyp verursacht mehr Overhead als die Verwendung derselben Logik in der Abfrage. Wenn sie also mehrmals pro Sekunde aufgerufen wird, können Sie mithilfe einer Funktion erhebliche Ressourcen verbrauchen. Ich verstehe, dass dies aus zahlreichen Codeteilen aufgerufen werden kann, so dass der Wunsch besteht, es zu einer Funktion zu machen, falls das Standarddatum geändert werden muss - dann werden keine kompilierten Codeänderungen vorgenommen und diese Funktion nur aktualisiert.
Wenn dieser Code häufig ausgeführt wird, sollten Sie andere Optionen in Betracht ziehen, die eine bessere Leistung als eine benutzerdefinierte Funktion bieten. In Salomos Antwort finden Sie eine Übersicht über Ihre Optionen und eine weitere Erklärung, warum Sie eine über die andere wählen könnten.
Im Folgenden wird beispielsweise dieselbe Logik gezeigt, die als Inline-Tabellenwertfunktion implementiert ist, die verwendet werden muss, CROSS APPLY
wenn kein statischer Wert angegeben wird, aber eine viel bessere Leistung als eine skalare UDF aufweist:
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
*/