Cuando crea una función con valores de tabla (TVF) en SQL Server, puede convertirla en una función con valores de tabla en línea (ITVF) o una función con valores de tabla de varias instrucciones (MSTVF). Existen diferencias entre estos tipos de funciones y, en consecuencia, usan una sintaxis diferente.
Este artículo cubre la diferencia entre MSTVF e ITVF.
Las diferencias
Estas son las principales diferencias entre MSTVF e ITVF.
ITVF | MSTVF | |
---|---|---|
La sintaxis de RETURNS | Simplemente indica RETURNS TABLE y la definición de la tabla de retorno se basará en SELECT de la función declaración. No es necesario especificar la estructura de la tabla de retorno. | Tus RETURNS la sintaxis especifica explícitamente la estructura de la tabla de retorno. Esto se hace declarando una variable TABLE que se usará para almacenar y acumular las filas que se devuelven como el valor de la función. |
La sintaxis BEGIN/END | Las ITVF no utilizan el BEGIN /END sintaxis. | Los MSTVF usan el BEGIN /END sintaxis. |
Rendimiento | Generalmente más rápido que los MTSVF. | Generalmente más lento que los ITVF. |
Actualizaciones de datos | En algunos casos, es posible actualizar los datos en las tablas subyacentes mediante un ITFV. | No puede actualizar los datos en las tablas subyacentes mediante un MSTVF. |
Sintaxis
Veamos las diferencias en la sintaxis de cada tipo de función.
Función con valores de tabla en línea
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 [ ) ] [ ; ]
Función con valores de tabla de declaraciones múltiples
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 [ ; ]
Tenga en cuenta que MSTVF comienza con una definición de tabla, pero ITVF no tiene tal definición.
El MSTVF comienza con RETURNS @return_variable TABLE
seguido de la definición de la tabla. Aquí, @return_variable
es una variable TABLE, utilizada para almacenar y acumular las filas que deben devolverse como el valor de la función.
Ejemplo 1:función con valores de tabla en línea
Aquí hay un ejemplo de una ITVF simple.
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
Aquí, selecciono de dos tablas usando UNION ALL
y la función simplemente devuelve el resultado.
Ejemplo 2:función con valores de tabla de declaraciones múltiples
Aquí hay un ejemplo del uso de un MSTVF para hacer lo mismo, pero de una manera 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
La función comienza declarando una variable TABLE llamada @pets
. Al hacer esto, especificamos explícitamente la estructura de la tabla de retorno.
Las consultas dentro del BEGIN
/END
bloque se guardan en la variable TABLE llamada @pets
.
En este caso, opté por no usar UNION ALL
. En cambio, ejecuté las instrucciones por separado y guardé los resultados de cada una en @pets
variables.
Ejemplo 3:agregar otra declaración al MSTVF
Para demostrar aún más el aspecto de "instrucciones múltiples" de los MSTVF, podemos agregar más declaraciones al MSTVF anterior y guardar los resultados en la misma variable de retorno.
Ejemplo:
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
En este caso, agregué un código para devolver un mensaje especial siempre que la consulta no devuelva filas.