Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Differenza tra funzioni con valori di tabella a più istruzioni e funzioni con valori di tabella inline in SQL Server

Quando si crea una funzione con valori di tabella (TVF) in SQL Server, è possibile renderla una funzione con valori di tabella in linea (ITVF) o una funzione con valori di tabella con istruzioni multiple (MSTVF). Esistono differenze tra questi tipi di funzione e di conseguenza utilizzano una sintassi diversa.

Questo articolo copre la differenza tra MSTVF e ITVF.

Le differenze

Ecco le principali differenze tra MSTVF e ITVF.

ITVF MSTVF
La sintassi RETURNS Dichiari semplicemente RETURNS TABLE e la definizione della tabella di ritorno sarà basata sul SELECT della funzione dichiarazione. Non è necessario specificare la struttura della tabella di ritorno. Il tuo RETURNS la sintassi specifica in modo esplicito la struttura della tabella di ritorno. Questo viene fatto dichiarando una variabile TABLE che verrà utilizzata per archiviare e accumulare le righe restituite come valore della funzione.
La sintassi BEGIN/END Gli ITVF non usano il BEGIN /END sintassi. Gli MSTVF usano il BEGIN /END sintassi.
Prestazioni Generalmente più veloce degli MTSVF. Generalmente più lento degli ITVF.
Aggiornamenti dei dati In alcuni casi è possibile aggiornare i dati nelle tabelle sottostanti utilizzando un ITFV. Non è possibile aggiornare i dati nelle tabelle sottostanti utilizzando un MSTVF.

Sintassi

Diamo un'occhiata alle differenze nella sintassi di ciascun tipo di funzione.

Funzione con valori di tabella in linea

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

Funzione con valori di tabella a più istruzioni

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

Si noti che MSTVF inizia con una definizione di tabella, ma ITVF non ha tale definizione.

Il MSTVF inizia con RETURNS @return_variable TABLE seguito dalla definizione della tabella. Qui, @return_variable è una variabile TABLE, utilizzata per memorizzare e accumulare le righe che devono essere restituite come valore della funzione.

Esempio 1 – Funzione inline con valori di tabella

Ecco un esempio di un semplice 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

Qui, seleziono da due tabelle usando UNION ALL e la funzione restituisce semplicemente il risultato.

Esempio 2 – Funzione con valori di tabella a più istruzioni

Ecco un esempio di utilizzo di un MSTVF per fare la stessa cosa, ma in un modo diverso.

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

La funzione inizia con la dichiarazione di una variabile TABLE chiamata @pets . In questo modo, specifichiamo esplicitamente la struttura della tabella di ritorno.

Le query all'interno di BEGIN /END blocco vengono salvati nella variabile TABLE chiamata @pets .

In questo caso, ho scelto di non utilizzare UNION ALL . Invece, ho eseguito le istruzioni separatamente e ho salvato i risultati di ciascuna in @pets variabile.

Esempio 3:aggiungere un'altra dichiarazione al MSTVF

Per dimostrare ulteriormente l'aspetto "multi-istruzione" degli MSTVF, possiamo aggiungere più istruzioni al MSTVF sopra e salvare i risultati nella stessa variabile di ritorno.

Esempio:

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

In questo caso ho aggiunto del codice per restituire un messaggio speciale ogni volta che la query non restituisce righe.