Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Criar um UDF vinculado ao esquema no SQL Server


No SQL Server, geralmente é uma boa ideia vincular o esquema às suas funções definidas pelo usuário (UDFs).

O esquema vinculando sua UDF garantirá que as tabelas subjacentes não possam ser alteradas de uma maneira que afete sua função. Sem vinculação de esquema, as tabelas subjacentes ou outros objetos podem ser modificados ou até mesmo excluídos. Fazer isso pode quebrar a função.



Para criar uma UDF vinculada ao esquema, use o WITH SCHEMABINDING em seu código T-SQL para criar a função. Isso se aplica se a função for uma função escalar ou uma função com valor de tabela (TVF).

De qualquer forma, incluí exemplos de um TVF inline, um TVF de várias instruções e uma função escalar.

Exemplo 1 – Função com valor de tabela embutido


Aqui está um exemplo de criação de um TVF embutido com vinculação 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 usei o nome de duas partes ao fazer referência à tabela em minha consulta (usei dbo.Cats ao fazer referência à tabela, em vez de apenas Cats ). Fazer isso é um requisito para o esquema vincular um objeto. Se você tentar vincular um objeto ao esquema sem usar nomes de duas partes, receberá um erro.

Agora que vinculei minha função ao esquema, se eu tentar descartar a tabela referenciada em sua definição, recebo um erro:
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'.

Aqui está o que acontece se eu tentar criar a função sem usar nomenclatura de duas 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.

Exemplo 2 - Função com valor de tabela de várias instruções


Com TVFs de várias instruções, você coloca WITH SCHEMABINDING após a especificação da variável 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

Exemplo 3 – Função escalar


Aqui está um exemplo de função 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

Exemplo 4 – Adicionando vários argumentos


Você pode especificar vários argumentos como uma lista separada por vírgulas. Por exemplo, se você deseja especificar a vinculação de esquema e criptografia, você precisará adicioná-los como uma lista separada por vírgulas.
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