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

Diferença entre funções com valor de tabela de várias instruções e funções com valor de tabela embutida no SQL Server


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.