Когато създавате функция с стойност на таблица (TVF) в SQL Server, можете да я направите вградена функция с таблично стойност (ITVF) или функция с таблично стойности с множество оператори (MSTVF). Има разлики между тези типове функции и съответно те използват различен синтаксис.
Тази статия обхваща разликата между MSTVF и ITVF.
Разликите
Ето основните разлики между MSTVF и ITVF.
| ITVF | MSTVF | |
|---|---|---|
| Синтаксисът RETURNS | Просто посочвате RETURNS TABLE и дефиницията на връщащата таблица ще се основава на SELECT на функцията изявление. Няма нужда да посочвате структурата на таблицата за връщане. | Вашето RETURNS синтаксисът изрично определя структурата на таблицата за връщане. Това се прави чрез деклариране на променлива TABLE, която ще се използва за съхраняване и натрупване на редовете, които се връщат като стойност на функцията. |
| Синтаксисът BEGIN/END | ITVF не използват BEGIN /END синтаксис. | MSTVF използват BEGIN /END синтаксис. |
| Изпълнение | Общо взето по-бързо от MTSVFs. | Общо взето по-бавно от ITVFs. |
| Актуализации на данните | В някои случаи е възможно да се актуализират данните в основните таблици с помощта на ITFV. | Не можете да актуализирате данните в основните таблици с помощта на MSTVF. |
Синтаксис
Нека разгледаме разликите в синтаксиса на всеки тип функция.
Вградена функция с таблично стойности
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 [ ) ]
[ ; ]
Функция с таблична стойност с множество изрази
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
[ ; ]
Забележете, че MSTVF започва с дефиниция на таблица, но ITVF няма такава дефиниция.
MSTVF започва с RETURNS @return_variable TABLE последвано от дефиницията на таблицата. Тук @return_variable е променлива TABLE, използвана за съхраняване и натрупване на редовете, които трябва да бъдат върнати като стойност на функцията.
Пример 1 – Вградена функция с таблично стойност
Ето пример за обикновен 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
Тук избирам от две таблици, използвайки UNION ALL , а функцията просто връща резултата.
Пример 2 – Функция с таблична стойност с множество изрази
Ето пример за използване на MSTVF, за да направите същото, но по различен начин.
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
Функцията започва с деклариране на TABLE променлива, наречена @pets . Правейки това, ние изрично указваме структурата на таблицата за връщане.
Заявките в BEGIN /END блок се записват в променливата TABLE, наречена @pets .
В този случай избрах да не използвам UNION ALL . Вместо това изпълних операторите поотделно и записах резултатите от всеки един в @pets променлива.
Пример 3 – Добавете още едно изявление към MSTVF
За да демонстрираме по-нататък аспекта на „множество оператори“ на MSTVF, можем да добавим още изрази към горния MSTVF и да запазим резултатите в същата променлива за връщане.
Пример:
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
В този случай добавих някакъв код за връщане на специално съобщение, когато заявката не доведе до връщане на редове.