Le funzioni con valori di tabella sono viste parametrizzate "solo". Ciò li rende estremamente potenti per incapsulare la logica che altrimenti sarebbe nascosta dietro una stored procedure opaca. Ecco un esempio:
Funzione in linea con valori di tabella:
create function dbo.GetClients (
@clientName nvarchar(max) = null
)
returns table
return (
select *
from dbo.Clients as a
where ((a.ClientName = @clientName) or a.ClientName is null)
);
Procedura archiviata:
create procedure dbo.usp_GetClients (
@clientName nvarchar(max) = null
)
as
begin;
select *
from dbo.Clients as a
where ((a.ClientName = @clientName) or a.ClientName is null)
end;
A differenza della chiamata alla procedura memorizzata, una funzione con valori di tabella mi consente di comporre la logica da dbo.GetClients
con altri oggetti:
select *
from dbo.GetClients(N'ACME') as a
join ... as b
on a.ClientId = b.ClientId
In tali situazioni non riesco a immaginare di utilizzare una stored procedure a causa di quanto sia restrittiva rispetto alla funzione con valori di tabella. Sarei costretto a effettuare il marshalling dei dati intorno a me utilizzando una tabella temporanea, una variabile di tabella o un livello dell'applicazione per combinare i risultati di più oggetti.
Le funzioni inline con valori di tabella sono particolarmente fantastiche a causa del bit "inline" che probabilmente è spiegato meglio qui. Ciò consente all'ottimizzatore di trattare tali funzioni in modo non diverso dagli oggetti che incapsulano, ottenendo piani di prestazioni quasi ottimali (supponendo che gli indici e le statistiche siano ideali).