Kemungkinan besar alasan utamanya adalah Fungsi Table-Valued mengembalikan Set Hasil, sama seperti Tabel dan Tampilan. Ini berarti bahwa mereka dapat digunakan dalam FROM
ayat (termasuk JOIN
s dan APPLY
s, dll) dari SELECT
, UPDATE
, dan DELETE
query. Anda tidak bisa, bagaimanapun, menggunakan Scalar UDF dalam konteks apa pun itu.
Kedua, Anda juga bisa EXECUTE
menggunakan 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 DEFAULT
kata 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 EXECUTE
berfungsi, 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 EXEC
sintaks 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 @Dummy
variabel;
NAMUN, dengan EXEC
sintaks, 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 EXEC
sintaks, maka dimungkinkan untuk juga menggunakan WITH RECOMPILE
opsi 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;