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.