Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Erstellen Sie eine schemagebundene UDF in SQL Server

In SQL Server ist es normalerweise eine gute Idee, Ihre benutzerdefinierten Funktionen (UDFs) an ein Schema zu binden.

Die Schemabindung Ihrer UDF stellt sicher, dass die zugrunde liegenden Tabellen nicht auf eine Weise geändert werden können, die Ihre Funktion beeinträchtigen würde. Ohne Schemabindung könnten die zugrunde liegenden Tabellen oder andere Objekte geändert oder sogar gelöscht werden. Dadurch könnte die Funktion unterbrochen werden.

Um eine schemagebundene UDF zu erstellen, verwenden Sie WITH SCHEMABINDING in Ihrem T-SQL-Code zum Erstellen der Funktion. Dies gilt unabhängig davon, ob es sich bei der Funktion um eine Skalarfunktion oder eine Tabellenwertfunktion (TVF) handelt.

Auf jeden Fall habe ich Beispiele für eine Inline-TVF, eine TVF mit mehreren Anweisungen und eine Skalarfunktion eingefügt.

Beispiel 1 – Inline-Tabellenwertfunktion

Hier ist ein Beispiel für die Erstellung eines Inline-TVF mit Schemabindung:

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

Beachten Sie, dass ich den zweiteiligen Namen verwendet habe, als ich in meiner Abfrage auf die Tabelle verwiesen habe (ich habe dbo.Cats verwendet wenn auf die Tabelle verwiesen wird, statt nur Cats ). Dies ist eine Voraussetzung für die Schemabindung eines Objekts. Wenn Sie versuchen, ein Objekt an ein Schema zu binden, ohne zweiteilige Namen zu verwenden, erhalten Sie eine Fehlermeldung.

Jetzt, da ich meine Funktion schemagebunden habe, erhalte ich eine Fehlermeldung, wenn ich versuche, die Tabelle, auf die in ihrer Definition verwiesen wird, zu löschen:

DROP TABLE Cats;

Ergebnis:

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

Folgendes passiert, wenn ich versuche, die Funktion ohne zweiteilige Benennung zu erstellen:

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

Ergebnis:

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.

Beispiel 2 – Tabellenwertfunktion mit mehreren Anweisungen

Bei TVFs mit mehreren Anweisungen platzieren Sie WITH SCHEMABINDING nach der Angabe der Rückgabevariable.

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

Beispiel 3 – Skalarfunktion

Hier ist ein Beispiel für eine 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

Beispiel 4 – Hinzufügen mehrerer Argumente

Sie können mehrere Argumente als durch Kommas getrennte Liste angeben. Wenn Sie beispielsweise die Schemabindung und angeben möchten Verschlüsselung, dann müssen Sie diese als kommagetrennte Liste hinzufügen.

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