W SQL Server zazwyczaj dobrym pomysłem jest schematyczne powiązanie funkcji zdefiniowanych przez użytkownika (UDF).
Schemat wiążący Twój UDF zapewni, że nie można zmienić bazowych tabel w sposób, który wpłynąłby na twoją funkcję. Bez powiązania schematu bazowe tabele lub inne obiekty mogą być modyfikowane, a nawet usuwane. Może to spowodować uszkodzenie funkcji.
Aby utworzyć powiązany ze schematem UDF, użyj WITH SCHEMABINDING
w kodzie T-SQL do tworzenia funkcji. Ma to zastosowanie niezależnie od tego, czy funkcja jest funkcją skalarną, czy funkcją z wartościami tabelarycznymi (TVF).
W każdym razie podałem przykłady wbudowanego TVF, wielowyrazowego TVF i funkcji skalarnej.
Przykład 1 – Wbudowana funkcja z wartościami tabelarycznymi
Oto przykład tworzenia wbudowanego TVF z powiązaniem schematu:
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
Zauważ, że użyłem dwuczęściowej nazwy podczas odwoływania się do tabeli w moim zapytaniu (użyłem dbo.Cats
podczas odwoływania się do tabeli, zamiast po prostu Cats
). Jest to wymagane do powiązania obiektu ze schematem. Jeśli spróbujesz powiązać obiekt w schemacie bez użycia dwuczęściowych nazw, otrzymasz błąd.
Teraz, gdy powiązałem schemat z moją funkcją, jeśli spróbuję usunąć tabelę, do której odwołuje się jej definicja, otrzymuję błąd:
DROP TABLE Cats;
Wynik:
Msg 3729, Level 16, State 1, Line 1 Cannot DROP TABLE 'cats' because it is being referenced by object 'udf_CatsByName_ITVF'.
Oto, co się stanie, jeśli spróbuję utworzyć funkcję bez używania dwuczęściowego nazewnictwa:
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
Wynik:
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.
Przykład 2 – Wielowyrazowa funkcja z wartościami tabelarycznymi
W przypadku wielowyrazowych plików TVF umieszczasz WITH SCHEMABINDING
po specyfikacji zwracanej zmiennej.
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
Przykład 3 – Funkcja skalarna
Oto przykład funkcji skalarnej:
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
Przykład 4 – Dodawanie wielu argumentów
Możesz podać wiele argumentów jako listę rozdzielaną przecinkami. Na przykład, jeśli chcesz określić powiązanie schematu i szyfrowanie, musisz je dodać jako listę oddzieloną przecinkami.
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