sql >> Databáze >  >> RDS >> Sqlserver

Rozdíl mezi vícepříkazovými tabulkovými funkcemi a vloženými tabulkovými funkcemi na serveru SQL Server

Když vytvoříte funkci s hodnotou tabulky (TVF) na serveru SQL Server, můžete z ní udělat buď funkci s hodnotou tabulky vloženou hodnotou (ITVF) nebo funkci s hodnotou tabulky s více příkazy (MSTVF). Mezi těmito typy funkcí jsou rozdíly a podle toho používají jinou syntaxi.

Tento článek popisuje rozdíl mezi MSTVF a ITVF.

Rozdíly

Zde jsou hlavní rozdíly mezi MSTVF a ITVF.

ITVF MSTVF
Syntaxe RETURNS Stačí uvést RETURNS TABLE a definice návratové tabulky bude založena na SELECT funkce prohlášení. Není třeba specifikovat strukturu návratové tabulky. Vaše RETURNS syntaxe explicitně specifikuje strukturu návratové tabulky. To se provádí deklarováním proměnné TABLE, která bude použita k uložení a akumulaci řádků, které jsou vráceny jako hodnota funkce.
Syntaxe BEGIN/END ITVF nepoužívají BEGIN /END syntaxe. MSTVF používají BEGIN /END syntaxe.
Výkon Obecně rychlejší než MTSVF. Obecně pomalejší než ITVF.
Aktualizace dat V některých případech je možné aktualizovat data v podkladových tabulkách pomocí ITFV. Nemůžete aktualizovat data v podkladových tabulkách pomocí MSTVF.

Syntaxe

Podívejme se na rozdíly v syntaxi jednotlivých typů funkcí.

Inline Table-Valued Function

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 [ ) ]  
[ ; ]  

Funkce s tabulkovou hodnotou s více příkazy

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  
[ ; ]

Všimněte si, že MSTVF začíná definicí tabulky, ale ITVF žádnou takovou definici nemá.

MSTVF začíná RETURNS @return_variable TABLE následuje definice tabulky. Zde @return_variable je proměnná TABLE, která se používá k ukládání a akumulaci řádků, které by měly být vráceny jako hodnota funkce.

Příklad 1 – Inline Table-Valued Function

Zde je příklad jednoduchého 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

Zde vybírám ze dvou tabulek pomocí UNION ALL a funkce jednoduše vrátí výsledek.

Příklad 2 – Funkce s tabulkovou hodnotou s více příkazy

Zde je příklad použití MSTVF k provedení stejné věci, ale jiným způsobem.

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

Funkce začíná deklarací proměnné TABLE s názvem @pets . Přitom explicitně specifikujeme strukturu návratové tabulky.

Dotazy uvnitř BEGIN /END blok se uloží do proměnné TABLE s názvem @pets .

V tomto případě jsem se rozhodl nepoužít UNION ALL . Místo toho jsem provedl příkazy samostatně a uložil výsledky každého z nich do @pets proměnná.

Příklad 3 – Přidání dalšího příkazu do MSTVF

Abychom dále demonstrovali „vícepříkazový“ aspekt MSTVF, můžeme do výše uvedeného MSTVF přidat další příkazy a uložit výsledky do stejné návratové proměnné.

Příklad:

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

V tomto případě jsem přidal nějaký kód, který vrátí speciální zprávu vždy, když dotaz nevrací žádné řádky.


  1. Jak najít nejpomalejší dotazy

  2. Jak deklarovat proměnnou v MySQL?

  3. Převeďte z MySQL datetime do jiného formátu pomocí PHP

  4. MySQL ekvivalent Oracle SEQUENCE.NEXTVAL