sql >> Database >  >> RDS >> Sqlserver

Een schemagebonden UDF maken in SQL Server

In SQL Server is het meestal een goed idee om uw door de gebruiker gedefinieerde functies (UDF's) te schemabinden.

Schemabinding aan uw UDF zorgt ervoor dat de onderliggende tabellen niet kunnen worden gewijzigd op een manier die uw functie zou beïnvloeden. Zonder schemabinding kunnen de onderliggende tabellen of andere objecten worden gewijzigd of zelfs verwijderd. Als u dit doet, kan de functie worden verbroken.

Om een ​​schemagebonden UDF te maken, gebruikt u de WITH SCHEMABINDING in uw T-SQL-code voor het maken van de functie. Dit geldt ongeacht of de functie een scalaire functie of een tabelwaardefunctie (TVF) is.

Ik heb in ieder geval voorbeelden toegevoegd van een inline TVF, een multi-statement TVF en een scalaire functie.

Voorbeeld 1 – Inline tabel gewaardeerde functie

Hier is een voorbeeld van het maken van een inline TVF met schemabinding:

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

Merk op dat ik de tweedelige naam gebruikte bij het verwijzen naar de tabel in mijn zoekopdracht (ik gebruikte dbo.Cats bij het verwijzen naar de tabel, in plaats van alleen Cats ). Dit is een vereiste om een ​​object via een schema te binden. Als u een object via een schema probeert te binden zonder tweedelige namen te gebruiken, krijgt u een foutmelding.

Nu ik mijn functie schema gebonden heb, krijg ik een foutmelding als ik probeer de tabel waarnaar in de definitie wordt verwezen te laten vallen:

DROP TABLE Cats;

Resultaat:

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

Dit is wat er gebeurt als ik de functie probeer te maken zonder tweedelige naamgeving te gebruiken:

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

Resultaat:

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.

Voorbeeld 2 – Multi-statement tabel gewaardeerde functie

Met multi-statement TVF's plaats je WITH SCHEMABINDING na de specificatie van de retourvariabele.

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

Voorbeeld 3 – Scalaire functie

Hier is een voorbeeld van een scalaire functie:

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

Voorbeeld 4 – Meerdere argumenten toevoegen

U kunt meerdere argumenten opgeven als een door komma's gescheiden lijst. Als u bijvoorbeeld schemabinding en . wilt specificeren encryptie, dan moet je deze toevoegen als een door komma's gescheiden lijst.

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

  1. Hoe converteer ik een tijdstempel naar een datum/tijd in MySQL?

  2. Hoe een kolom in SQL te laten vallen?

  3. Meest recente rij ophalen voor gegeven ID

  4. Transactie-isolatie in PostgreSQL