Швидше за все, основною причиною є те, що функції, націлені на таблицю, повертають набір результатів, як і таблиці та представлення. Це означає , що вони можуть бути використані в FROM
пункті ( в тому числі JOIN
з і APPLY
з, і так далі) з SELECT
, UPDATE
і DELETE
запитів. Однак ви не можете використовувати Скалярну СДС в жодному з цих контекстів.
По-друге, ви також EXECUTE
можете скалярний АДС. Цей синтаксис є досить зручним, коли для вхідних параметрів у вас є значення за замовчуванням. Візьмемо, наприклад, наступну УДС:
CREATE FUNCTION dbo.OptionalParameterTest (@Param1 INT = 1, @Param2 INT = 2)
RETURNS INT
AS
BEGIN
RETURN @Param1 + @Param2;
END;
Якщо ви хочете розглянути будь-який з вхідних параметрів як "необов'язковий", вам все одно потрібно ввести DEFAULT
ключове слово, викликаючи його як функцію, оскільки підпис фіксовано:
DECLARE @Bob1 INT;
SET @Bob1 = dbo.OptionalParameterTest(100, DEFAULT);
SELECT @Bob1;
-- Returns: 102
З іншого боку, якщо ви EXECUTE
функціонуєте, ви можете розглядати будь-які параметри зі значенням за замовчуванням як справді необов’язкові, як і у випадку із збереженими процедурами. Ви можете передати перші n параметрів, не вказуючи назви параметрів:
DECLARE @Bob2 INT;
EXEC @Bob2 = dbo.OptionalParameterTest 50;
SELECT @Bob2;
-- Returns: 52
Можна навіть пропустити перший параметр, знову ж таки, вказавши імена параметрів, як і у випадку Збережені процедури:
DECLARE @Bob3 INT;
EXEC @Bob3 = dbo.OptionalParameterTest @Param2 = 50;
SELECT @Bob3;
-- Returns: 51
ОНОВЛЕННЯ
Чому ви можете використовувати EXEC
синтаксис для виклику скалярного UDF так само, як збережена процедура? Іноді є UDF, які мають велике значення як UDF, оскільки вони можуть бути додані до запиту та діяти над поверненим рядом рядків, тоді як якщо код був у Збереженій процедурі, його потрібно буде помістити в курсор, щоб повторити набір рядків. Але тоді трапляються випадки, коли ви хочете викликати цю функцію за одним значенням, можливо, з іншого UDF. Виклик UDF для одного значення може здійснюватися як:
SELECT dbo.UDF('some value');
у такому випадку ви отримуєте повернене значення у наборі результатів (набір результатів не працюватиме). Або це можна зробити так:
DECLARE @Dummy INT;
SET @Dummy = dbo.UDF('some value');
в такому випадку вам потрібно оголосити @Dummy
змінну;
ЗАРАЗ, за допомогою EXEC
синтаксису, ви можете уникнути обох цих неприємностей:
EXEC dbo.UDF 'some value';
ТАКОЖ, скалярні АДС мають кешовані плани виконання. Це означає, що можна зіткнутися з проблемами нюху параметрів, якщо в UDF є запити, які мають плани виконання. Для сценаріїв, де доцільно використовувати EXEC
синтаксис, можна також скористатися WITH RECOMPILE
опцією ігнорувати значення складеного планами для цього виконання . Наприклад:
НАСТРОЙКА:
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
ТЕСТ:
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;