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.