Kemungkinan besar alasan utamanya adalah Fungsi Table-Valued mengembalikan Set Hasil, sama seperti Tabel dan Tampilan. Ini berarti bahwa mereka dapat digunakan dalam FROMayat (termasuk JOINs dan APPLYs, dll) dari SELECT, UPDATE, dan DELETEquery. Anda tidak bisa, bagaimanapun, menggunakan Scalar UDF dalam konteks apa pun itu.
Kedua, Anda juga bisa EXECUTEmenggunakan UDF Skalar. Sintaks ini cukup berguna ketika Anda memiliki nilai default yang ditentukan untuk parameter input. Ambil UDF berikut, misalnya:
CREATE FUNCTION dbo.OptionalParameterTest (@Param1 INT = 1, @Param2 INT = 2)
RETURNS INT
AS
BEGIN
RETURN @Param1 + @Param2;
END;
Jika Anda ingin memperlakukan salah satu parameter input sebagai "opsional", Anda masih harus memasukkan DEFAULTkata kunci saat memanggilnya seperti fungsi karena tanda tangan diperbaiki:
DECLARE @Bob1 INT;
SET @Bob1 = dbo.OptionalParameterTest(100, DEFAULT);
SELECT @Bob1;
-- Returns: 102
Di sisi lain, jika Anda EXECUTEberfungsi, maka Anda dapat memperlakukan parameter apa pun dengan nilai default sebagai benar-benar opsional, sama seperti yang Anda bisa dengan Prosedur Tersimpan. Anda dapat memasukkan n parameter pertama tanpa menentukan nama parameter:
DECLARE @Bob2 INT;
EXEC @Bob2 = dbo.OptionalParameterTest 50;
SELECT @Bob2;
-- Returns: 52
Anda bahkan dapat melewati parameter pertama dengan menentukan nama parameter, sekali lagi, sama seperti dengan Prosedur Tersimpan:
DECLARE @Bob3 INT;
EXEC @Bob3 = dbo.OptionalParameterTest @Param2 = 50;
SELECT @Bob3;
-- Returns: 51
MEMPERBARUI
Mengapa Anda ingin menggunakan EXECsintaks untuk memanggil skalar UDF seperti Prosedur yang Disimpan? Kadang-kadang ada UDF yang bagus untuk dimiliki sebagai UDF karena mereka dapat ditambahkan ke kueri dan beroperasi di atas set baris yang dikembalikan, sedangkan jika kode berada dalam Prosedur Tersimpan maka perlu ditempatkan ke dalam kursor untuk beralih pada satu set baris. Tetapi kemudian ada saat-saat Anda ingin memanggil fungsi itu pada nilai tunggal, mungkin dari dalam UDF lain. Memanggil UDF untuk nilai tunggal dapat dilakukan sebagai:
SELECT dbo.UDF('some value');
dalam hal ini Anda mendapatkan nilai kembali di set hasil (set hasil tidak akan berfungsi). Atau bisa juga dilakukan sebagai berikut:
DECLARE @Dummy INT;
SET @Dummy = dbo.UDF('some value');
dalam hal ini Anda perlu mendeklarasikan @Dummyvariabel;
NAMUN, dengan EXECsintaks, Anda dapat menghindari kedua gangguan tersebut:
EXEC dbo.UDF 'some value';
JUGA, skalar UDF memiliki rencana eksekusi yang di-cache. Ini berarti bahwa ada kemungkinan untuk mengalami masalah sniffing parameter jika ada pertanyaan di UDF yang memiliki rencana eksekusi. Untuk skenario di mana layak untuk menggunakan EXECsintaks, maka dimungkinkan untuk juga menggunakan WITH RECOMPILEopsi untuk mengabaikan rencana nilai yang dikompilasi untuk eksekusi itu . Sebagai contoh:
MEMPERSIAPKAN:
GO
CREATE FUNCTION dbo.TestUDF (@Something INT)
RETURNS INT
AS
BEGIN
DECLARE @Ret INT;
SELECT @Ret = COUNT(*)
FROM sys.indexes si
WHERE si.[index_id] = @Something;
RETURN @Ret;
END;
GO
UJI:
DECLARE @Val INT;
SET @Val = dbo.TestUDF(1);
SELECT @Val;
EXEC @Val = dbo.TestUDF 0 -- uses compiled value of (1)
SELECT @Val;
EXEC @Val = dbo.TestUDF 0 WITH RECOMPILE; -- uses compiled value of (0)
SELECT @Val;
EXEC @Val = dbo.TestUDF 3 -- uses compiled value of (1)
SELECT @Val;