sql >> Database teknologi >  >> RDS >> Sqlserver

Opret en skemabundet UDF i SQL Server

I SQL Server er det normalt en god idé at skemabinde dine brugerdefinerede funktioner (UDF'er).

Skemabinding af din UDF vil sikre, at de underliggende tabeller ikke kan ændres på en måde, der vil påvirke din funktion. Uden skemabinding kan de underliggende tabeller eller andre objekter ændres eller endda slettes. Dette kan ødelægge funktionen.

For at oprette en skemabundet UDF skal du bruge WITH SCHEMABINDING i din T-SQL-kode for at oprette funktionen. Dette gælder uanset om funktionen er en skalarfunktion eller en tabelværdi-funktion (TVF).

Under alle omstændigheder har jeg inkluderet eksempler på en inline TVF, en multi-statement TVF og en skalar funktion.

Eksempel 1 – Inline-tabel-vurderet funktion

Her er et eksempel på oprettelse af en inline TVF med skemabinding:

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

Bemærk, at jeg brugte det todelte navn, når jeg refererede til tabellen i min forespørgsel (jeg brugte dbo.Cats når man refererer til tabellen, i stedet for kun Cats ). At gøre dette er et krav for skemabinding af et objekt. Hvis du forsøger at skemabinde et objekt uden at bruge todelte navne, får du en fejl.

Nu hvor jeg har skemabundet min funktion, får jeg en fejlmeddelelse, hvis jeg forsøger at droppe tabellen, der henvises til i dens definition:

DROP TABLE Cats;

Resultat:

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

Her er, hvad der sker, hvis jeg forsøger at oprette funktionen uden at bruge todelt navngivning:

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

Resultat:

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.

Eksempel 2 – Multi-erklærings-tabel-værdi-funktion

Med multi-statement TVF'er placerer du WITH SCHEMABINDING efter returneringsvariabelspecifikationen.

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

Eksempel 3 – Skalær funktion

Her er et eksempel på en skalarfunktion:

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

Eksempel 4 – Tilføjelse af flere argumenter

Du kan angive flere argumenter som en kommasepareret liste. For eksempel, hvis du ønsker at angive skemabinding og kryptering, så skal du tilføje disse som en kommasepareret liste.

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. execSQL() med OPDATERING opdateres ikke

  2. PostgreSQL forkert sortering

  3. Annoncering af ClusterControl 1.7.3:Forbedret support PostgreSQL og nye cloud-implementeringsmuligheder

  4. Advarsel:PDO::__construct():[2002] Ingen sådan fil eller mappe (forsøger at oprette forbindelse via unix:///tmp/mysql.sock) i