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.