Najprawdopodobniej głównym powodem jest to, że funkcje wyceniane w tabeli zwracają zestaw wyników, podobnie jak tabele i widoki. Oznacza to, że mogą one być stosowane w FROM
klauzuli (włączając JOIN
s i APPLY
s, etc.) z SELECT
, UPDATE
i DELETE
zapytań. Nie można jednak użyć Skalarnego UDF w żadnym z tych kontekstów.
Po drugie, możesz także EXECUTE
Skalarny UDF. Ta składnia jest bardzo przydatna, gdy określono wartości domyślne parametrów wejściowych. Weźmy na przykład następujący UDF:
CREATE FUNCTION dbo.OptionalParameterTest (@Param1 INT = 1, @Param2 INT = 2)
RETURNS INT
AS
BEGIN
RETURN @Param1 + @Param2;
END;
Jeśli chcesz traktować którykolwiek z parametrów wejściowych jako „opcjonalny”, nadal musisz podać DEFAULT
słowo kluczowe, nazywając go jak funkcję, ponieważ podpis jest stały:
DECLARE @Bob1 INT;
SET @Bob1 = dbo.OptionalParameterTest(100, DEFAULT);
SELECT @Bob1;
-- Returns: 102
Z drugiej strony, jeśli masz EXECUTE
tę funkcję, możesz traktować dowolne parametry o wartości domyślnej jako naprawdę opcjonalne, tak jak możesz to zrobić za pomocą procedur przechowywanych. Możesz przekazać pierwsze n parametrów bez określania nazw parametrów:
DECLARE @Bob2 INT;
EXEC @Bob2 = dbo.OptionalParameterTest 50;
SELECT @Bob2;
-- Returns: 52
Możesz nawet pominąć pierwszy parametr, ponownie określając nazwy parametrów, podobnie jak w przypadku procedur przechowywanych:
DECLARE @Bob3 INT;
EXEC @Bob3 = dbo.OptionalParameterTest @Param2 = 50;
SELECT @Bob3;
-- Returns: 51
AKTUALIZACJA
Dlaczego możesz chcieć użyć EXEC
składni do wywołania skalarnego UDF, tak jak procedura przechowywana? Czasami istnieją UDF, które świetnie nadają się jako UDF, ponieważ można je dodawać do zapytania i operować na zestawie zwróconych wierszy, natomiast jeśli kod był w procedurze przechowywanej, należy go umieścić w kursorze, aby iterować po zestawie wierszy. Ale są chwile, kiedy chcesz wywołać tę funkcję na jednej wartości, być może z innego UDF. Wywołanie UDF dla pojedynczej wartości można wykonać jako:
SELECT dbo.UDF('some value');
w takim przypadku otrzymasz wartość zwracaną w zestawie wyników (zestaw wyników nie będzie działać). Lub można to zrobić w następujący sposób:
DECLARE @Dummy INT;
SET @Dummy = dbo.UDF('some value');
w takim przypadku musisz zadeklarować @Dummy
zmienną;
JEDNAK dzięki EXEC
składni możesz uniknąć obu tych niedogodności:
EXEC dbo.UDF 'some value';
TAKŻE, skalarne UDF mają buforowane swoje plany wykonania. Oznacza to, że można napotkać problemy z wąchaniem parametrów, jeśli w UDF są zapytania zawierające plany wykonania. W przypadku scenariuszy, w których możliwe jest użycie EXEC
składni, można również użyć WITH RECOMPILE
opcji zignorowania wartości skompilowanej planu dla tego wykonania . Na przykład:
USTAWIAĆ:
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
TEST:
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;