Podczas tworzenia funkcji z wartościami przechowywanymi w tabeli (TVF) w programie SQL Server można ustawić ją jako wbudowaną funkcję z wartościami przechowywanymi w tabeli (ITVF) lub funkcję z wartościami przechowywanymi w tabeli z wieloma instrukcjami (MSTVF). Istnieją różnice między tymi typami funkcji i odpowiednio używają one innej składni.
W tym artykule omówiono różnicę między MSTVF i ITVF.
Różnice
Oto główne różnice między MSTVF i ITVF.
ITVF | MSTVF | |
---|---|---|
Składnia ZWROTÓW | Po prostu podajesz RETURNS TABLE a definicja tabeli zwracanej będzie oparta na funkcji SELECT oświadczenie. Nie ma potrzeby określania struktury tabeli zwrotów. | Twoje RETURNS składnia jawnie określa strukturę tabeli zwracanej. Odbywa się to poprzez zadeklarowanie zmiennej TABLE, która będzie używana do przechowywania i gromadzenia wierszy zwracanych jako wartość funkcji. |
Składnia POCZĄTEK/KONIEC | ITVF nie używają BEGIN /END składnia. | MSTVF używają BEGIN /END składnia. |
Wydajność | Zazwyczaj szybciej niż MTSVF. | Zazwyczaj wolniej niż ITVF. |
Aktualizacje danych | W niektórych przypadkach możliwa jest aktualizacja danych w bazowych tabelach za pomocą ITFV. | Nie można aktualizować danych w bazowych tabelach za pomocą MSTVF. |
Składnia
Przyjrzyjmy się różnicom w składni każdego typu funkcji.
Wbudowana funkcja z wartościami tabelarycznymi
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ = default ] [ READONLY ] } [ ,...n ] ] ) RETURNS TABLE [ WITH <function_option> [ ,...n ] ] [ AS ] RETURN [ ( ] select_stmt [ ) ] [ ; ]
Funkcja z wieloma wyrażeniami tabelarycznymi
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ = default ] [READONLY] } [ ,...n ] ] ) RETURNS @return_variable TABLE <table_type_definition> [ WITH <function_option> [ ,...n ] ] [ AS ] BEGIN function_body RETURN END [ ; ]
Zauważ, że MSTVF zaczyna się od definicji tabeli, ale ITVF nie ma takiej definicji.
MSTVF zaczyna się od RETURNS @return_variable TABLE
po której następuje definicja tabeli. Tutaj, @return_variable
jest zmienną TABLE, używaną do przechowywania i gromadzenia wierszy, które powinny zostać zwrócone jako wartość funkcji.
Przykład 1 – Wbudowana funkcja z wartościami tabelarycznymi
Oto przykład prostego ITVF.
CREATE FUNCTION udf_PetsByName_ITVF( @PetName varchar(70)) RETURNS TABLE AS RETURN ( SELECT CONCAT('Cat', ' ', CatId) AS PetId, CatName FROM dbo.Cats WHERE CatName = @PetName UNION ALL SELECT CONCAT('Dog', ' ', DogId) AS PetId, DogName FROM dbo.Dogs WHERE DogName = @PetName ); GO
Tutaj wybieram z dwóch tabel za pomocą UNION ALL
, a funkcja po prostu zwraca wynik.
Przykład 2 – Wielowyrazowa funkcja z wartościami tabelarycznymi
Oto przykład użycia MSTVF do zrobienia tego samego, ale w inny sposób.
CREATE FUNCTION udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) 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; RETURN; END; GO
Funkcja zaczyna się od zadeklarowania zmiennej TABLE o nazwie @pets
. Robiąc to, wyraźnie określamy strukturę tabeli zwrotów.
Zapytania wewnątrz BEGIN
/END
bloki są zapisywane w zmiennej TABLE o nazwie @pets
.
W tym przypadku zdecydowałem się nie używać UNION ALL
. Zamiast tego wykonałem instrukcje osobno i zapisałem wyniki każdego z nich w @pets
zmienna.
Przykład 3 – Dodaj kolejną instrukcję do MSTVF
Aby dodatkowo zademonstrować aspekt „wielozdaniowy” MSTVF, możemy dodać więcej instrukcji do powyższego MSTVF i zapisać wyniki w tej samej zwracanej zmiennej.
Przykład:
CREATE FUNCTION udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) 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
W tym przypadku dodałem kod, który zwraca specjalną wiadomość za każdym razem, gdy zapytanie nie powoduje zwrócenia żadnych wierszy.