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