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.