Ao criar uma função com valor de tabela (TVF) no SQL Server, você pode torná-la uma função com valor de tabela embutida (ITVF) ou uma função com valor de tabela de várias instruções (MSTVF). Existem diferenças entre esses tipos de função e eles usam uma sintaxe diferente de acordo.
Este artigo aborda a diferença entre MSTVFs e ITVFs.
As diferenças
Aqui estão as principais diferenças entre MSTVFs e ITVFs.
ITVF | MSTVF | |
---|---|---|
A sintaxe de RETURNS | Você simplesmente declara RETURNS TABLE e a definição da tabela de retorno será baseada no SELECT da função demonstração. Não há necessidade de especificar a estrutura da tabela de retorno. | Seus RETURNS sintaxe especifica explicitamente a estrutura da tabela de retorno. Isso é feito declarando uma variável TABLE que será usada para armazenar e acumular as linhas que são retornadas como o valor da função. |
A sintaxe BEGIN/END | ITVFs não usam o BEGIN /END sintaxe. | MSTVFs usam o BEGIN /END sintaxe. |
Desempenho | Geralmente mais rápido que os MTSVFs. | Geralmente mais lento que ITVFs. |
Atualizações de dados | Em alguns casos, é possível atualizar dados nas tabelas subjacentes usando um ITFV. | Você não pode atualizar dados nas tabelas subjacentes usando um MSTVF. |
Sintaxe
Vejamos as diferenças na sintaxe de cada tipo de função.
Função com valor de tabela embutido
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ = default ] [ READONLY ] } [ ,...n ] ] ) RETURNS TABLE [ WITH <function_option> [ ,...n ] ] [ AS ] RETURN [ ( ] select_stmt [ ) ] [ ; ]
Função com valor de tabela de várias instruções
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ = default ] [READONLY] } [ ,...n ] ] ) RETURNS @return_variable TABLE <table_type_definition> [ WITH <function_option> [ ,...n ] ] [ AS ] BEGIN function_body RETURN END [ ; ]
Observe que o MSTVF inicia com uma definição de tabela, mas o ITVF não possui tal definição.
O MSTVF começa com
RETURNS @return_variable TABLE
seguido pela definição da tabela. Aqui, @return_variable
é uma variável TABLE, usada para armazenar e acumular as linhas que devem ser retornadas como o valor da função. Exemplo 1 – Função com valor de tabela embutido
Aqui está um exemplo de um ITVF simples.
CREATE FUNCTION udf_PetsByName_ITVF( @PetName varchar(70)) RETURNS TABLE AS RETURN ( SELECT CONCAT('Cat', ' ', CatId) AS PetId, CatName FROM dbo.Cats WHERE CatName = @PetName UNION ALL SELECT CONCAT('Dog', ' ', DogId) AS PetId, DogName FROM dbo.Dogs WHERE DogName = @PetName ); GO
Aqui, eu seleciono entre duas tabelas usando
UNION ALL
, e a função simplesmente retorna o resultado. Exemplo 2 - Função com valor de tabela de várias instruções
Aqui está um exemplo de uso de um MSTVF para fazer a mesma coisa, mas de uma maneira diferente.
CREATE FUNCTION udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) 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; RETURN; END; GO
A função começa declarando uma variável TABLE chamada
@pets
. Ao fazer isso, especificamos explicitamente a estrutura da tabela de retorno. As consultas dentro do
BEGIN
/END
bloco são salvos na variável TABLE chamada @pets
. Nesse caso, optei por não usar
UNION ALL
. Em vez disso, executei as instruções separadamente e salvei os resultados de cada uma no @pets
variável. Exemplo 3 – Adicionar outra declaração ao MSTVF
Para demonstrar ainda mais o aspecto “multi-instrução” dos MSTVFs, podemos adicionar mais instruções ao MSTVF acima e salvar os resultados na mesma variável de retorno.
Exemplo:
CREATE FUNCTION udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) 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
Nesse caso, adicionei algum código para retornar uma mensagem especial sempre que a consulta não resultar em nenhuma linha retornada.