När du skapar en tabellvärderad funktion (TVF) i SQL Server kan du antingen göra den till en inline-tabellvärderad funktion (ITVF) eller en tabellvärderad funktion med flera påståenden (MSTVF). Det finns skillnader mellan dessa funktionstyper, och de använder en annan syntax i enlighet därmed.
Den här artikeln tar upp skillnaden mellan MSTVFs och ITVFs.
Skillnaderna
Här är de viktigaste skillnaderna mellan MSTVFs och ITVFs.
| ITVF | MSTVF | |
|---|---|---|
| RETURNS-syntaxen | Du anger bara RETURNS TABLE och returtabellens definition kommer att baseras på funktionens SELECT påstående. Du behöver inte ange strukturen för returtabellen. | Dina RETURNS syntax anger uttryckligen strukturen för returtabellen. Detta görs genom att deklarera en TABLE-variabel som kommer att användas för att lagra och ackumulera de rader som returneras som värdet på funktionen. |
| BÖRJAN/SLUT-syntaxen | ITVF:er använder inte BEGIN /END syntax. | MSTVF använder BEGIN /END syntax. |
| Prestanda | Generellt snabbare än MTSVF. | Generellt långsammare än ITVF. |
| Datauppdateringar | I vissa fall är det möjligt att uppdatera data i de underliggande tabellerna med en ITFV. | Du kan inte uppdatera data i de underliggande tabellerna med en MSTVF. |
Syntax
Låt oss titta på skillnaderna i syntaxen för varje funktionstyp.
Inline tabellvärderad funktion
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 [ ) ]
[ ; ]
Tabellvärderad funktion med flera påståenden
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
[ ; ]
Lägg märke till att MSTVF börjar med en tabelldefinition, men ITVF har ingen sådan definition.
MSTVF börjar med RETURNS @return_variable TABLE följt av tabelldefinitionen. Här, @return_variable är en TABLE-variabel, som används för att lagra och ackumulera raderna som ska returneras som värdet på funktionen.
Exempel 1 – Inline tabellvärderad funktion
Här är ett exempel på en enkel 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
Här väljer jag från två tabeller med UNION ALL , och funktionen returnerar helt enkelt resultatet.
Exempel 2 – Multi-Statement Tabell-värderad funktion
Här är ett exempel på hur man använder en MTVF för att göra samma sak, men på ett annat sätt.
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
Funktionen börjar med att deklarera en TABLE-variabel som heter @pets . När vi gör detta specificerar vi uttryckligen strukturen för returtabellen.
Frågorna i BEGIN /END blocket sparas i TABLE-variabeln som heter @pets .
I det här fallet valde jag att inte använda UNION ALL . Istället körde jag satserna separat och sparade resultaten av var och en till @pets variabel.
Exempel 3 – Lägg till ytterligare ett uttalande till MSTVF
För att ytterligare demonstrera "multi-statement"-aspekten av MTVF:er kan vi lägga till fler satser till ovanstående MTVF och spara resultaten i samma returvariabel.
Exempel:
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
I det här fallet lade jag till en kod för att returnera ett speciellt meddelande när frågan resulterar i att inga rader returneras.