sql >> Base de Datos >  >> RDS >> Sqlserver

Crear una UDF enlazada a un esquema en SQL Server

En SQL Server, suele ser una buena idea vincular mediante esquemas las funciones definidas por el usuario (UDF).

El enlace de esquema de su UDF garantizará que las tablas subyacentes no se puedan cambiar de una manera que afecte su función. Sin vinculación de esquema, las tablas subyacentes u otros objetos podrían modificarse o incluso eliminarse. Hacer esto podría romper la función.

Para crear una UDF enlazada a un esquema, use WITH SCHEMABINDING en su código T-SQL para crear la función. Esto se aplica ya sea que la función sea una función escalar o una función con valores de tabla (TVF).

En cualquier caso, he incluido ejemplos de un TVF en línea, un TVF de varias instrucciones y una función escalar.

Ejemplo 1:función con valores de tabla en línea

Este es un ejemplo de creación de un TVF en línea con enlace de esquema:

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

Observe que usé el nombre de dos partes al hacer referencia a la tabla en mi consulta (usé dbo.Cats al hacer referencia a la tabla, en lugar de solo Cats ). Hacer esto es un requisito para el enlace de esquema de un objeto. Si intenta enlazar un objeto mediante un esquema sin usar nombres de dos partes, obtendrá un error.

Ahora que he enlazado el esquema de mi función, si trato de eliminar la tabla a la que se hace referencia en su definición, aparece un error:

DROP TABLE Cats;

Resultado:

Msg 3729, Level 16, State 1, Line 1
Cannot DROP TABLE 'cats' because it is being referenced by object 'udf_CatsByName_ITVF'.

Esto es lo que sucede si trato de crear la función sin usar nombres de dos partes:

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

Resultado:

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.

Ejemplo 2:función con valores de tabla de declaraciones múltiples

Con TVF de varias instrucciones, coloca WITH SCHEMABINDING después de la especificación de la variable de retorno.

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

Ejemplo 3:función escalar

Aquí hay un ejemplo de función escalar:

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

Ejemplo 4:agregar varios argumentos

Puede especificar varios argumentos como una lista separada por comas. Por ejemplo, si desea especificar el enlace de esquema y encriptación, entonces deberá agregarlos como una lista separada por comas.

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