Vous pouvez créer une fonction table multi-instructions (MSTVF) dans SQL Server à l'aide de T-SQL CREATE FUNCTION
syntaxe.
Syntaxe
Voici la syntaxe officielle des TVF 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[ ,...n ] ] [ AS ] BEGIN function_body RETURN END [ ; ]
Exemple 1 – MSTVF de base
Voici un exemple de fonction table multi-instructions.
CREATE FUNCTION dbo.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
La structure de la table de retour est définie au début lorsque je spécifie le @pets
variable. Les résultats de la requête sont insérés dans le @pets
variables.
Dans ce cas, la fonction nécessite qu'un nom d'animal de compagnie soit transmis en tant qu'argument. Il utilise ensuite cet argument dans les requêtes afin de renvoyer les données pertinentes. Être un multi -fonction de table d'instructions, je peux inclure plusieurs instructions dans la définition de la fonction.
Exemple 2 – Ajouter une liaison de schéma
C'est généralement une bonne idée de lier le schéma de vos fonctions en utilisant le SCHEMABINDING
argument.
Cela garantira que les tables sous-jacentes ne peuvent pas être modifiées d'une manière qui affecterait votre fonction.
Sans liaison de schéma, les tables sous-jacentes pourraient être modifiées ou même supprimées. Cela pourrait casser la fonction.
Voici la même fonction, mais cette fois avec une liaison de schéma :
CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) WITH SCHEMABINDING 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
Remarquez que j'ai utilisé des noms en deux parties lors du référencement des tables dans ma requête (j'ai utilisé dbo.Cats
et dbo.Dogs
lors de la référence à la table, au lieu de simplement Cats
ou Dogs
). Cela est une exigence pour le schéma de liaison d'un objet. Si vous essayez de lier un objet au schéma sans utiliser de noms en deux parties, vous obtiendrez une erreur.
Maintenant que j'ai lié le schéma de ma fonction, si j'essaie de supprimer la table référencée dans sa définition, j'obtiens une erreur :
DROP TABLE Dogs;
Résultat :
Msg 3729, Level 16, State 1, Line 1 Cannot DROP TABLE 'Dogs' because it is being referenced by object 'udf_PetsByName_MSTVF'.
Au fait, voici ce qui se passe si j'essaie de créer la fonction sans utiliser de nommage en deux parties :
CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) WITH SCHEMABINDING AS BEGIN INSERT INTO @pets SELECT CONCAT('Cat', ' ', CatId), CatName FROM Cats WHERE CatName = @PetName; INSERT INTO @pets SELECT CONCAT('Dog', ' ', DogId), DogName FROM Dogs WHERE DogName = @PetName; IF @@ROWCOUNT = 0 BEGIN INSERT INTO @pets VALUES ( '', 'There are no pets of that name.' ) END RETURN; END; GO
Résultat :
Msg 4512, Level 16, State 3, Procedure udf_PetsByName_MSTVF, Line 10 Cannot schema bind table valued function 'dbo.udf_PetsByName_MSTVF' because name 'Cats' is invalid for schema binding. Names must be in two-part format and an object cannot reference itself.
Exemple 3 – Ajouter un chiffrement
Vous pouvez également chiffrer vos fonctions en utilisant le ENCRYPTION
argument.
Voici un exemple de cryptage de la fonction :
CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) WITH SCHEMABINDING, ENCRYPTION 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
Je ne parviens plus à afficher la définition de la fonction.
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('udf_PetsByName_MSTVF');
Résultat :
+--------------+ | definition | |--------------| | NULL | +--------------+
Je reçois également un message d'erreur lorsque j'essaie de scripter la définition de la fonction via Azure Data Studio :
No script was returned when scripting as Create on object UserDefinedFunction
Notez que le texte d'une fonction chiffrée est toujours disponible pour les utilisateurs privilégiés qui peuvent soit accéder aux tables système via le port DAC, soit accéder directement aux fichiers de la base de données. De plus, les utilisateurs qui peuvent attacher un débogueur au processus serveur peuvent récupérer la procédure d'origine de la mémoire lors de l'exécution.