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