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

Creare un'UDF associata a schema in SQL Server

In SQL Server, di solito è una buona idea associare a uno schema le tue funzioni definite dall'utente (UDF).

L'associazione dello schema alla tua UDF assicurerà 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 o altri oggetti potrebbero essere modificati o addirittura eliminati. Ciò potrebbe interrompere la funzione.

Per creare una UDF legata allo schema, usa WITH SCHEMABINDING nel tuo codice T-SQL per creare la funzione. Ciò vale se la funzione è una funzione scalare o una funzione con valori di tabella (TVF).

In ogni caso, ho incluso esempi di TVF in linea, TVF con più istruzioni e una funzione scalare.

Esempio 1 – Funzione inline con valori di tabella

Ecco un esempio di creazione di un TVF inline con associazione 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'.

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 2 – Funzione con valori di tabella a più istruzioni

Con le TVF con più dichiarazioni, inserisci WITH SCHEMABINDING dopo la specifica della variabile di ritorno.

CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70))
    RETURNS @pets TABLE (
        PetId varchar(20),
        PetName varchar(70)
    )
    WITH SCHEMABINDING
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

Esempio 3 – Funzione scalare

Ecco un esempio di funzione scalare:

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;

GO

Esempio 4 – Aggiunta di più argomenti

È possibile specificare più argomenti come un elenco separato da virgole. Ad esempio, se si desidera specificare l'associazione dello schema e crittografia, quindi dovrai aggiungerli come un elenco separato da virgole.

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