Pada SQL Server 2012 dan yang lebih baru Anda dapat menggunakan TRY_CONVERT untuk memeriksa untuk melihat apakah input dapat dikonversi. Jika tidak, nilai NULL dikembalikan sehingga Anda dapat melakukan COALESCE untuk mendapatkan nilai yang dikonversi atau tanggal tetap.
begin
declare @result date
set @result = COALESCE(TRY_CONVERT(date, @date, 111), '2012-01-01')
return @result
end
Anda juga bisa menggunakan TRY CATCH
blok dan mengembalikan tanggal tetap di CATCH
blok, tetapi praktik terbaik untuk menggunakan TRY_CONVERT sehingga SQL Server tidak harus menangani kesalahan karena membutuhkan lebih banyak waktu dan sumber daya.
Suatu fungsi untuk jenis kode ini akan menimbulkan lebih banyak overhead daripada hanya menggunakan logika yang sama dalam kueri, jadi jika itu dipanggil berkali-kali setiap detik Anda mungkin mengunyah sumber daya yang signifikan dengan menggunakan fungsi untuknya. Saya mengerti bahwa ini dapat dipanggil dari berbagai bagian kode sehingga ada keinginan untuk menjadikannya fungsi jika tanggal default perlu diubah - maka tidak ada perubahan kode yang dikompilasi dan perbarui saja fungsi ini.
Jika kode ini akan banyak berjalan, Anda harus mempertimbangkan opsi lain yang akan memberikan kinerja yang lebih baik daripada fungsi yang ditentukan pengguna. Silakan lihat jawaban Solomon untuk ikhtisar opsi Anda dan penjelasan lebih lanjut mengapa Anda memilih satu di atas yang lain.
Sebagai contoh, berikut ini menunjukkan logika yang sama diimplementasikan sebagai fungsi bernilai tabel inline, yang perlu digunakan CROSS APPLY
jika tidak disertakan dengan nilai statis, tetapi berkinerja jauh lebih baik daripada skalar 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
*/