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

Creare una funzione scalare definita dall'utente in SQL Server

In SQL Server è possibile creare una funzione scalare definita dall'utente utilizzando CREATE FUNCTION dichiarazione. Una funzione scalare definita dall'utente, altrimenti nota come UDF scalare, è una funzione definita dall'utente che restituisce un singolo valore.

Questo articolo contiene esempi di creazione di alcune UDF scalari T-SQL di base.

Sintassi

Per prima cosa, diamo un'occhiata alla sintassi per la creazione di UDF scalari.

La sintassi per le UDF scalari T-SQL è la seguente:

 
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   
( [ { @parameter_name [ AS ][ type_schema_name. ] parameter_data_type   
    [ = default ] [ READONLY ] }   
    [ ,...n ]  
  ]  
)  
RETURNS return_data_type  
    [ WITH <function_option> [ ,...n ] ]  
    [ AS ]  
    BEGIN   
        function_body   
        RETURN scalar_expression  
    END  
[ ; ]

E la sintassi per le UDF scalari CLR:

 
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   
( { @parameter_name [AS] [ type_schema_name. ] parameter_data_type   
    [ = default ] }   
    [ ,...n ]  
)  
RETURNS { return_data_type }  
    [ WITH <clr_function_option> [ ,...n ] ]  
    [ AS ] EXTERNAL NAME   
[ ; ]  

Le parti in <function_option> per le funzioni T-SQL e <clr_function_option> per le funzioni CLR consentono di specificare le opzioni per l'UDF. Le opzioni delle funzioni includono l'aggiunta di crittografia, associazione dello schema, un EXECUTE AS clausola, oltre a specificare cosa fare quando un valore NULL viene passato come argomento.

Un elenco completo di argomenti e opzioni di funzione è disponibile sul sito Web di Microsoft.

La documentazione Microsoft contiene molti dettagli, quindi i seguenti esempi hanno lo scopo di fornire una rapida panoramica di alcuni concetti e opzioni comuni durante la creazione di UDF scalari.

Esempio 1 – UDF scalare di base

Ecco un esempio del codice utilizzato per creare una UDF scalare T-SQL di base.

CREATE FUNCTION dbo.ufn_discountPrice( 
    @price DECIMAL(12,2), 
    @discount DECIMAL(12,2) 
    ) 
RETURNS DECIMAL (12,2)
AS
BEGIN
  RETURN @price * (1 - @discount);
END;

Questa UDF scalare accetta due parametri; @price e @discount . Questi vengono passati alla funzione come argomenti ogni volta che la funzione viene invocata. La funzione prende il valore di quegli argomenti, esegue un calcolo utilizzando quei valori, quindi restituisce il valore risultante. In questo caso viene restituito il prezzo scontato.

Esempio 2 – Richiamare l'UDF

Una volta che l'UDF è stato creato, può essere invocato all'interno del codice T-SQL ogni volta che ne hai bisogno.

Ecco un esempio di richiamo dell'UDF:

SELECT dbo.ufn_discountPrice(100, .2) AS Result;

Risultato

+----------+
| Result   |
|----------|
| 80.00    |
+----------+

Esempio 3 – Interrogazione di una tabella

Le UDF scalari possono anche fare cose come le tabelle di database di query.

Eccone uno che restituisce il numero di album presenti nel database per un determinato artista.

CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  
RETURNS smallint
AS  
BEGIN  
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;

Questa è una funzione scalare perché restituisce un singolo valore. Se volessimo restituire un elenco di album, dovremmo utilizzare una funzione con valori di tabella, perché le funzioni con valori di tabella restituiscono i risultati come un insieme di righe.

Esempio 4 – Associazione di schemi

Quando crei una funzione definita dall'utente che dipende da altri oggetti nel database, in genere è una buona idea associare a uno schema l'UDF. L'associazione dello schema dell'UDF garantisce che non sia possibile apportare modifiche agli oggetti sottostanti che potrebbero potenzialmente influire sulla funzione.

Ad esempio, non saresti in grado di eliminare una tabella utilizzata da un'UDF associata a uno schema nella sua definizione.

Per associare allo schema un UDF, usa WITH SCHEMABINDING nella sua definizione. È inoltre necessario utilizzare nomi in due parti per tutti gli oggetti a cui si fa riferimento nell'UDF.

Ecco l'esempio precedente riscritto in modo che sia legato allo schema:

CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  
RETURNS smallint
WITH SCHEMABINDING
AS  
BEGIN  
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM dbo.Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;

Quindi, ho cambiato due cose rispetto al primo esempio. Ho aggiunto WITH SCHEMABINDING e ho cambiato Albums a dbo.Albums .

Ora, se qualcuno tenta di eliminare quella tabella o di apportare altre modifiche, riceverà un errore.

Esempio 5 – Crittografia

Puoi anche usare WITH ENCRYPTION per crittografare la funzione.

CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  
RETURNS smallint
WITH ENCRYPTION
AS  
BEGIN  
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM dbo.Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;

Esempio 6 – Input NULL

Quando si richiama la funzione, se uno qualsiasi degli argomenti è NULL, il corpo della funzione viene comunque eseguito. Cioè, a meno che tu non abbia dichiarato esplicitamente RETURNS NULL ON NULL INPUT nella definizione della funzione.

Specificando tale opzione restituirà NULL se uno qualsiasi degli argomenti è NULL.

CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  
RETURNS smallint
WITH RETURNS NULL ON NULL INPUT
AS  
BEGIN  
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM dbo.Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;

Quando invoco la funzione usando NULL come argomento:

SELECT dbo.ufn_CountAlbums(NULL) AS Result;

Ottengo un risultato diverso, a seconda di ciò che ho specificato per questa opzione.

Ecco il risultato quando la funzione utilizza l'impostazione predefinita (CALLED ON NULL INPUT ):

+----------+
| Result   |
|----------|
| 0        |
+----------+

Ed ecco il risultato quando usa RETURNS NULL ON NULL INPUT :

+----------+
| Result   |
|----------|
| NULL     |
+----------+

Esempio 7 – Opzioni multiple

Puoi separare più opzioni con una virgola.

Ecco un esempio che aggiunge sia la crittografia che il binding dello schema alla funzione:

CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  
RETURNS smallint
WITH ENCRYPTION, SCHEMABINDING
AS  
BEGIN  
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM dbo.Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;

Esempio 8 – Modifica di una funzione

Puoi modificare una UDF scalare sostituendo CREATE con ALTER .

ALTER FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  
RETURNS smallint
WITH SCHEMABINDING
AS  
BEGIN  
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM dbo.Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;