La raison principale est probablement que les fonctions table renvoient un ensemble de résultats, tout comme les tables et les vues. Cela signifie qu'ils peuvent être utilisés dans la FROM
clause (y compris JOIN
s et APPLY
s, etc.) de SELECT
, UPDATE
et les DELETE
requêtes. Cependant, vous ne pouvez pas utiliser une FDU Scalar dans aucun de ces contextes.
Secondairement, vous pouvez également EXECUTE
un UDF Scalaire. Cette syntaxe est très pratique lorsque des valeurs par défaut sont spécifiées pour les paramètres d'entrée. Prenez par exemple l'UDF suivant:
CREATE FUNCTION dbo.OptionalParameterTest (@Param1 INT = 1, @Param2 INT = 2)
RETURNS INT
AS
BEGIN
RETURN @Param1 + @Param2;
END;
Si vous souhaitez traiter l'un des paramètres d'entrée comme "facultatif", vous devez toujours saisir le DEFAULT
mot - clé lorsque vous l'appelez comme une fonction car la signature est fixe:
DECLARE @Bob1 INT;
SET @Bob1 = dbo.OptionalParameterTest(100, DEFAULT);
SELECT @Bob1;
-- Returns: 102
D'un autre côté, si vous EXECUTE
utilisez la fonction, vous pouvez traiter tous les paramètres avec une valeur par défaut comme vraiment optionnels, tout comme vous le pouvez avec les procédures stockées. Vous pouvez passer les n premiers paramètres sans spécifier de noms de paramètres:
DECLARE @Bob2 INT;
EXEC @Bob2 = dbo.OptionalParameterTest 50;
SELECT @Bob2;
-- Returns: 52
Vous pouvez même ignorer le premier paramètre en spécifiant des noms de paramètres, à nouveau, comme avec les procédures stockées:
DECLARE @Bob3 INT;
EXEC @Bob3 = dbo.OptionalParameterTest @Param2 = 50;
SELECT @Bob3;
-- Returns: 51
MISE À JOUR
Pourquoi voudriez-vous utiliser la EXEC
syntaxe pour appeler une UDF scalaire comme une procédure stockée? Parfois, il y a des UDF qui sont géniaux d'avoir comme UDF car ils peuvent être ajoutés à une requête et opérer sur l'ensemble des lignes retournées, alors que si le code était dans une procédure stockée, il devrait être placé dans un curseur afin de itérer sur un ensemble de lignes. Mais il y a des moments où vous voulez appeler cette fonction sur une seule valeur, peut-être à partir d'un autre UDF. L'appel d'un UDF pour une valeur unique peut se faire comme suit:
SELECT dbo.UDF('some value');
dans ce cas, vous obtenez une valeur de retour dans un jeu de résultats (un jeu de résultats ne fonctionnera pas). Ou cela pourrait être fait comme suit:
DECLARE @Dummy INT;
SET @Dummy = dbo.UDF('some value');
dans ce cas, vous devez déclarer la @Dummy
variable;
CEPENDANT, avec la EXEC
syntaxe, vous pouvez éviter ces deux désagréments:
EXEC dbo.UDF 'some value';
AUSSI, les FDU scalaires ont leurs plans d'exécution mis en cache. Cela signifie qu'il est possible de rencontrer des problèmes de détection de paramètres s'il existe des requêtes dans l'UDF qui ont des plans d'exécution. Pour les scénarios où il est possible d'utiliser la EXEC
syntaxe, il est également possible d'utiliser l' WITH RECOMPILE
option pour ignorer la valeur compilée des plans pour cette exécution . Par exemple:
INSTALLER:
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
TESTER:
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;