Когато създавате функция с стойност на таблица (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
В този случай добавих някакъв код за връщане на специално съобщение, когато заявката не доведе до връщане на редове.