Condividi tramite


Esecuzione di funzioni definite dall'utente (Motore di database)

Le funzioni definite dall'utente possono essere richiamate in query o in altre istruzioni o espressioni, ad esempio le colonne calcolate o le espressioni stringa. Le funzioni a valori scalari possono essere eseguite utilizzando l'istruzione EXECUTE.

Richiamata di funzioni definite dall'utente che restituiscono un valore scalare

È possibile richiamare una funzione definita dall'utente che restituisce un valore scalare in qualsiasi posizione di un'istruzione Transact-SQL in cui sia consentita un'espressione scalare con lo stesso tipo di dati. Le funzioni a valori scalari devono essere richiamate utilizzando almeno il nome composto da due parti della funzione. Per ulteriori informazioni sui nomi composti da più parti, vedere Convenzioni della sintassi Transact-SQL (Transact-SQL).

Query

Le funzioni definite dall'utente che restituiscono valori scalari sono consentite nelle posizioni seguenti:

  • Come parametro expression in select_list di un'istruzione SELECT:

    USE AdventureWorks;
    GO
    SELECT ProductID, ListPrice, dbo.ufnGetProductDealerPrice(ProductID, StartDate) AS DealerPrice,
        StartDate, EndDate
    FROM Production.ProductListPriceHistory
    WHERE ListPrice > .0000
    ORDER BY ProductID, StartDate;
    GO
    
  • Come parametro expression o string_expression nel predicato di una clausola WHERE o HAVING:

    USE AdventureWorks;
    GO
    SELECT ProductID, ListPrice, StartDate, EndDate
    FROM Production.ProductListPriceHistory
    WHERE dbo.ufnGetProductDealerPrice(ProductID, StartDate) > .0000
    ORDER BY ProductID, StartDate;
    GO
    
  • Come parametro group_by_expression in una clausola GROUP BY.

  • Come parametro order_by_expression in una clausola ORDER BY.

  • Come parametro expression nella clausola SET di un'istruzione UPDATE:

    USE AdventureWorks;
    GO
    UPDATE Production.ProductListPriceHistory
    SET ListPrice = dbo.ufnGetProductDealerPrice(ProductID, StartDate)
    WHERE ProductID > 900;
    GO
    
  • Come parametro expression nella clausola VALUES di un'istruzione INSERT:

    Le funzioni definite dall'utente a cui si fa riferimento in queste posizioni vengono eseguite logicamente una volta per riga.

Vincoli CHECK

Le funzioni definite dall'utente che restituiscono valori scalari possono essere richiamate tramite vincoli CHECK se i valori degli argomenti passati alla funzione fanno riferimento solo a colonne della tabella o a costanti. Ogni volta che Query Processor verifica il vincolo, viene richiamata la funzione con i valori degli argomenti associati alla riga verificata. Il proprietario di una tabella deve essere anche il proprietario della funzione definita dall'utente richiamata da un vincolo CHECK della tabella.

Definizioni DEFAULT

Le funzioni definite dall'utente possono essere richiamate come parametro constant_expression di definizioni DEFAULT se i valori degli argomenti passati alla funzione includono solo costanti. Il proprietario della tabella deve essere anche il proprietario della funzione definita dall'utente richiamata da una definizione DEFAULT della tabella.

Colonne calcolate

Le funzioni possono essere richiamate da colonne calcolate se i valori degli argomenti passati alla funzione fanno riferimento solo a colonne della tabella o a costanti. Il proprietario della tabella deve essere anche il proprietario della funzione definita dall'utente richiamata da una colonna calcolata della tabella.

Operatori di assegnazione

Gli operatori di assegnazione (left_operand = right_operand) possono richiamare funzioni definite dall'utente che restituiscono un valore scalare nell'espressione specificata come operando destro.

Istruzioni per il controllo di flusso

Le funzioni definite dall'utente che restituiscono valori scalari possono essere richiamate da istruzioni per il controllo di flusso nelle rispettive espressioni booleane.

Espressioni CASE

Le funzioni definite dall'utente che restituiscono valori scalari possono essere richiamate in qualsiasi espressione CASE.

Istruzioni PRINT

Le funzioni definite dall'utente che restituiscono una stringa di caratteri possono essere richiamate come espressione string_expr di istruzioni PRINT.

Funzioni e stored procedure

  • Gli argomenti delle funzioni possono essere inoltre riferimenti a una funzione definita dall'utente che restituisce un valore scalare.

  • Le istruzioni RETURN integer_expression incluse in stored procedure possono richiamare funzioni definite dall'utente che restituiscono un valore integer come parametro integer_expression.

  • Le istruzioni RETURN return_type_spec incluse in funzioni definite dall'utente possono richiamare funzioni definite dall'utente che restituiscono un tipo di dati scalare, ad esempio return_type_spec, a condizione che il valore restituito dalla funzione definita dall'utente possa essere convertito implicitamente nel tipo di dati restituito dalla funzione chiamante.

Esecuzione di funzioni definite dall'utente che restituiscono un valore scalare

Le funzioni definite dall'utente che restituiscono valori scalari possono essere eseguite in base alle stesse modalità utilizzate per le stored procedure. Quando si esegue una funzione definita dall'utente che restituisce un valore scalare, i parametri vengono specificati come per le stored procedure:

  • I valori degli argomenti non vengono racchiusi tra parentesi.

  • È possibile specificare i nomi dei parametri.

  • Se vengono specificati i nomi dei parametri, i valori degli argomenti non devono essere necessariamente specificati nella stessa sequenza dei parametri.

Nell'esempio seguente viene creata una funzione definita dall'utente che restituisce un valore scalare decimale.

IF OBJECT_ID(N'dbo.ufn_CubicVolume', N'FN') IS NOT NULL
    DROP FUNCTION dbo.ufn_CubicVolume;
GO
CREATE FUNCTION dbo.ufn_CubicVolume
-- Input dimensions in centimeters.
   (@CubeLength decimal(4,1), @CubeWidth decimal(4,1),
    @CubeHeight decimal(4,1) )
RETURNS decimal(12,3) -- Cubic Centimeters.
WITH SCHEMABINDING
AS
BEGIN
   RETURN ( @CubeLength * @CubeWidth * @CubeHeight )
END;
GO

Nell'esempio seguente viene eseguita la funzione dbo.ufn_CubicVolume. Nell'istruzione Transact-SQL EXECUTE gli argomenti vengono identificati in un ordine diverso rispetto a quello dei parametri inclusi nella definizione della funzione:

DECLARE @MyDecimalVar decimal(12,3);
EXEC @MyDecimalVar = dbo.ufn_CubicVolume @CubeLength = 12.3,
                        @CubeHeight = 4.5, @CubeWidth = 4.5;
SELECT @MyDecimalVar;
GO

Nell'esempio seguente viene eseguita la funzione dbo.ufn_CubicVolume senza che vengano specificati i nomi dei parametri:

DECLARE @MyDecimalVar decimal(12,3);
EXEC @MyDecimalVar = dbo.ufn_CubicVolume 12.3, 4.5, 4.5;
SELECT @MyDecimalVar;
GO

È inoltre possibile utilizzare la sintassi ODBC CALL per eseguire la funzione dbo.ufn_CubicVolume in applicazioni OLE DB o ODBC:

-- First use SQLBindParam to bind the return value parameter marker
-- to a program variable of the appropriate type
SQLExecDirect(hstmt,
              "{ CALL ? = dbo.ufn_CubicVolume(12.3, 4.5, 4.5) }",
              SQL_NTS);

Richiamata di funzioni definite dall'utente che restituiscono il tipo di dati table

È possibile richiamare una funzione definita dall'utente che restituisce il tipo di dati table in qualsiasi posizione in cui sono consentite espressioni relative a tabelle nella clausola FROM delle istruzioni SELECT, INSERT, UPDATE e DELETE. La richiamata di una funzione definita dall'utente che restituisce una tabella può essere seguita da un alias di tabella facoltativo. Nell'esempio seguente viene illustrata la chiamata della funzione con valori di tabella dbo.ufnGetContactInformation nella clausola FROM di un'istruzione SELECT.

USE AdventureWorks;
GO
SELECT ContactID, FirstName, LastName, JobTitle, ContactType
FROM dbo.ufnGetContactInformation(2200);
GO
SELECT ContactID, FirstName, LastName, JobTitle, ContactType
FROM dbo.ufnGetContactInformation(5);
GO

Se nella clausola FROM di una sottoquery si richiama una funzione definita dall'utente che restituisce una tabella, negli argomenti della funzione non è possibile fare riferimento a colonne della query esterna.

In un'istruzione SELECT in cui la clausola FROM fa riferimento a una funzione definita dall'utente che restituisce una tabella, è possibile aprire esclusivamente cursori statici di sola lettura.

Un'istruzione SELECT che fa riferimento a una funzione definita dall'utente che restituisce dati di tipo table richiama tale funzione una sola volta.

Richiamata di funzioni con valori di tabella predefinite

Sono disponibili diverse funzioni con valori di tabella predefinite che restituiscono un valore di tabella. È possibile richiamare tali funzioni definite dall'utente in modalità non qualificata oppure utilizzando il qualificatore di schema sys. È consigliabile utilizzare il qualificatore di schema sys per le funzioni con valori di tabella predefinite, in quanto consente di evitare conflitti con le funzioni definite dall'utente aventi lo stesso nome. Nell'esempio seguente viene illustrato come richiamare la funzione di sistema predefinita fn_helpcollations.

SELECT *
FROM sys.fn_helpcollations();
GO

Utilizzo di hint con funzioni con valori di tabella

Quando si crea una funzione definita dall'utente, è possibile applicare un hint di tabella in qualsiasi query che forma la definizione di funzione. Gli hint applicati alle viste che fanno riferimento a funzioni Transact-SQL con valori di tabella vengono applicati anche alle funzioni. Tali funzioni possono creare conflitti con gli hint inclusi nella definizione di funzione. Per ulteriori informazioni, vedere Risoluzione delle viste.

Non è possibile applicare hint in viste che fanno riferimento a funzioni CLR con valori di tabella.

[!NOTA]

La possibilità in Motore di database di applicare hint delle viste a funzioni con valori di tabella con istruzioni multiple che fanno parte della definizione della vista verrà rimossa a partire da una delle prossime versioni di SQL Server.

Evitare di applicare un hint di tabella al risultato di qualsiasi funzione con valori di tabella nella clausola FROM di una query.