È possibile creare una funzione inline con valori di tabella (ITVF) in SQL Server utilizzando T-SQL CREATE FUNCTION
sintassi.
Sintassi
Ecco la sintassi ufficiale per i TVF 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 [ ) ] [ ; ]
Esempio 1 – ITVF di base
Ecco un esempio di una funzione di base con valori di tabella in linea.
CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) ) RETURNS TABLE AS RETURN ( SELECT CatId, CatName, Phone FROM dbo.Cats WHERE CatName = @CatName ); GO
In questo caso, la funzione richiede che un nome cat venga passato come argomento. Quindi utilizza questo argomento nella query per restituire i dati rilevanti.
Esempio 2:aggiunta di associazione allo schema
Di solito è una buona idea associare allo schema le tue funzioni usando SCHEMABINDING
discussione.
In questo modo ti assicurerai che le tabelle sottostanti non possano essere modificate in un modo che potrebbe influire sulla tua funzione.
Senza l'associazione dello schema, le tabelle sottostanti potrebbero essere modificate o addirittura eliminate. Ciò potrebbe interrompere la funzione.
Ecco la stessa funzione, ma questa volta con il binding dello schema:
CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) ) RETURNS TABLE WITH SCHEMABINDING AS RETURN ( SELECT CatId, CatName, Phone FROM dbo.Cats WHERE CatName = @CatName ); GO
Nota che ho usato il nome in due parti quando ho fatto riferimento alla tabella nella mia query (ho usato dbo.Cats
quando si fa riferimento alla tabella, anziché solo a Cats
). Questa operazione è un requisito per lo schema vincolante di un oggetto. Se provi a associare allo schema un oggetto senza utilizzare nomi in due parti, riceverai un errore.
Ora che ho associato allo schema la mia funzione, se provo a eliminare la tabella a cui si fa riferimento nella sua definizione, ottengo un errore:
DROP TABLE Cats;
Risultato:
Msg 3729, Level 16, State 1, Line 1 Cannot DROP TABLE 'cats' because it is being referenced by object 'udf_CatsByName_ITVF'.
A proposito, ecco cosa succede se provo a creare la funzione senza usare la denominazione in due parti:
CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) ) RETURNS TABLE WITH SCHEMABINDING AS RETURN ( SELECT CatId, CatName, Phone FROM Cats WHERE CatName = @CatName ); GO
Risultato:
Msg 4512, Level 16, State 3, Procedure udf_CatsByName_ITVF, Line 7 Cannot schema bind table valued function 'dbo.udf_CatsByName_ITVF' because name 'Cats' is invalid for schema binding. Names must be in two-part format and an object cannot reference itself.
Esempio 3:aggiunta della crittografia
Puoi anche crittografare le tue funzioni usando ENCRYPTION
discussione.
Ecco un esempio di crittografia della funzione:
CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) ) RETURNS TABLE WITH SCHEMABINDING, ENCRYPTION AS RETURN ( SELECT CatId, CatName, Phone FROM dbo.Cats WHERE CatName = @CatName ); GO
Ora non riesco a visualizzare la definizione della funzione.
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('udf_CatsByName_ITVF');
Risultato:
+--------------+ | definition | |--------------| | NULL | +--------------+
Viene visualizzato anche un messaggio di errore quando si tenta di eseguire lo script della definizione della funzione tramite Azure Data Studio:
No script was returned when scripting as Create on object UserDefinedFunction
Si noti che il testo di una funzione crittografata è ancora disponibile per gli utenti privilegiati che possono accedere alle tabelle di sistema tramite la porta DAC o accedere direttamente ai file del database. Inoltre, gli utenti che possono collegare un debugger al processo del server possono recuperare la procedura originale dalla memoria in fase di esecuzione.