Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Créer une UDF liée au schéma dans SQL Server

Dans SQL Server, c'est généralement une bonne idée de lier au schéma vos fonctions définies par l'utilisateur (UDF).

Le schéma de liaison de votre UDF 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 ou d'autres objets pourraient être modifiés ou même supprimés. Cela pourrait casser la fonction.

Pour créer une UDF liée au schéma, utilisez le WITH SCHEMABINDING dans votre code T-SQL pour créer la fonction. Cela s'applique que la fonction soit une fonction scalaire ou une fonction table (TVF).

Dans tous les cas, j'ai inclus des exemples de TVF en ligne, de TVF multi-instructions et de fonction scalaire.

Exemple 1 – Fonction de table en ligne

Voici un exemple de création d'un TVF en ligne avec liaison de schéma :

CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) )
    RETURNS TABLE
    WITH SCHEMABINDING
AS
RETURN (
    SELECT 
        CatId,
        CatName,
        Phone
    FROM dbo.Cats
    WHERE CatName = @CatName
    );

GO

Remarquez que j'ai utilisé le nom en deux parties lors du référencement de la table dans ma requête (j'ai utilisé dbo.Cats lors de la référence à la table, au lieu de simplement Cats ). 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 Cats;

Résultat :

Msg 3729, Level 16, State 1, Line 1
Cannot DROP TABLE 'cats' because it is being referenced by object 'udf_CatsByName_ITVF'.

Voici ce qui se passe si j'essaie de créer la fonction sans utiliser de nommage en deux parties :

CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) )
    RETURNS TABLE
    WITH SCHEMABINDING
AS
RETURN (
    SELECT 
        CatId,
        CatName,
        Phone
    FROM Cats
    WHERE CatName = @CatName
    );

GO

Résultat :

Msg 4512, Level 16, State 3, Procedure udf_CatsByName_ITVF, Line 7
Cannot schema bind table valued function 'dbo.udf_CatsByName_ITVF' because name 'Cats' is invalid for schema binding. Names must be in two-part format and an object cannot reference itself.

Exemple 2 - Fonction table multi-instructions

Avec les TVF multi-instructions, vous placez WITH SCHEMABINDING après la spécification de la variable de retour.

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

Exemple 3 - Fonction scalaire

Voici un exemple de fonction scalaire :

CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  
RETURNS smallint
WITH SCHEMABINDING
AS  
BEGIN
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM dbo.Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;

GO

Exemple 4 - Ajouter plusieurs arguments

Vous pouvez spécifier plusieurs arguments sous forme de liste séparée par des virgules. Par exemple, si vous souhaitez spécifier la liaison de schéma et chiffrement, vous devrez alors les ajouter sous forme de liste séparée par des virgules.

CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) )
    RETURNS TABLE
    WITH SCHEMABINDING, ENCRYPTION
AS
RETURN (
    SELECT 
        CatId,
        CatName,
        Phone
    FROM dbo.Cats
    WHERE CatName = @CatName
    );

GO