Lorsque vous créez une fonction table (TVF) dans SQL Server, vous pouvez en faire une fonction table inline (ITVF) ou une fonction table multi-instructions (MSTVF). Il existe des différences entre ces types de fonctions, et ils utilisent une syntaxe différente en conséquence.
Cet article couvre la différence entre les MSTVF et les ITVF.
Les différences
Voici les principales différences entre les MSTVF et les ITVF.
ITVF | MSTVF | |
---|---|---|
La syntaxe RETURNS | Vous indiquez simplement RETURNS TABLE et la définition de la table de retour sera basée sur le SELECT de la fonction déclaration. Inutile de préciser la structure de la table de retour. | Vos RETURNS La syntaxe spécifie explicitement la structure de la table de retour. Cela se fait en déclarant une variable TABLE qui sera utilisée pour stocker et accumuler les lignes renvoyées comme valeur de la fonction. |
La syntaxe BEGIN/END | Les ITVF n'utilisent pas le BEGIN /END syntaxe. | Les MSTVF utilisent le BEGIN /END syntaxe. |
Performances | Généralement plus rapide que les MTSVF. | Généralement plus lent que les ITVF. |
Mises à jour des données | Dans certains cas, il est possible de mettre à jour les données dans les tables sous-jacentes à l'aide d'un ITFV. | Vous ne pouvez pas mettre à jour les données dans les tables sous-jacentes à l'aide d'un MSTVF. |
Syntaxe
Regardons les différences dans la syntaxe de chaque type de fonction.
Fonction de table en ligne
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ = default ] [ READONLY ] } [ ,...n ] ] ) RETURNS TABLE [ WITH <function_option> [ ,...n ] ] [ AS ] RETURN [ ( ] select_stmt [ ) ] [ ; ]
Fonction table multi-instructions
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ = default ] [READONLY] } [ ,...n ] ] ) RETURNS @return_variable TABLE <table_type_definition> [ WITH <function_option> [ ,...n ] ] [ AS ] BEGIN function_body RETURN END [ ; ]
Notez que le MSTVF commence par une définition de table, mais que le ITVF n'a pas une telle définition.
Le MSTVF commence par RETURNS @return_variable TABLE
suivi de la définition du tableau. Ici, @return_variable
est une variable TABLE, utilisée pour stocker et accumuler les lignes qui doivent être renvoyées comme valeur de la fonction.
Exemple 1 – Fonction de table en ligne
Voici un exemple d'un ITVF simple.
CREATE FUNCTION udf_PetsByName_ITVF( @PetName varchar(70)) RETURNS TABLE AS RETURN ( SELECT CONCAT('Cat', ' ', CatId) AS PetId, CatName FROM dbo.Cats WHERE CatName = @PetName UNION ALL SELECT CONCAT('Dog', ' ', DogId) AS PetId, DogName FROM dbo.Dogs WHERE DogName = @PetName ); GO
Ici, je sélectionne parmi deux tables en utilisant UNION ALL
, et la fonction renvoie simplement le résultat.
Exemple 2 - Fonction table multi-instructions
Voici un exemple d'utilisation d'un MSTVF pour faire la même chose, mais d'une manière différente.
CREATE FUNCTION udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) AS BEGIN INSERT INTO @pets SELECT CONCAT('Cat', ' ', CatId), CatName FROM dbo.Cats WHERE CatName = @PetName; INSERT INTO @pets SELECT CONCAT('Dog', ' ', DogId), DogName FROM dbo.Dogs WHERE DogName = @PetName; RETURN; END; GO
La fonction commence par déclarer une variable TABLE appelée @pets
. Ce faisant, nous spécifions explicitement la structure de la table de retour.
Les requêtes à l'intérieur du BEGIN
/END
bloc sont enregistrés dans la variable TABLE appelée @pets
.
Dans ce cas, j'ai choisi de ne pas utiliser UNION ALL
. Au lieu de cela, j'ai exécuté les instructions séparément et enregistré les résultats de chacune dans le @pets
variables.
Exemple 3 – Ajouter une autre instruction au MSTVF
Pour démontrer davantage l'aspect "multi-instructions" des MSTVF, nous pouvons ajouter plus d'instructions au MSTVF ci-dessus et enregistrer les résultats dans la même variable de retour.
Exemple :
CREATE FUNCTION udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) AS BEGIN INSERT INTO @pets SELECT CONCAT('Cat', ' ', CatId), CatName FROM dbo.Cats WHERE CatName = @PetName; INSERT INTO @pets SELECT CONCAT('Dog', ' ', DogId), DogName FROM dbo.Dogs WHERE DogName = @PetName; IF @@ROWCOUNT = 0 BEGIN INSERT INTO @pets VALUES ( '', 'There are no pets of that name.' ) END RETURN; END; GO
Dans ce cas, j'ai ajouté du code pour renvoyer un message spécial chaque fois que la requête ne renvoie aucune ligne.