Las funciones son rutinas que aceptan parámetros, realizan una acción y devuelven el resultado de esa acción como un valor escalar único o un conjunto de resultados.
Las funciones tienen ciertas limitaciones que no tienen los procedimientos:
- no se pueden ejecutar operaciones que modifiquen el estado de la base de datos.
- no pueden devolver varios conjuntos de resultados.
- no pueden llamar a un procedimiento almacenado (ejecutar exec)
- no admiten el control de errores TRY…CATCH
Esta es la sintaxis de una función escalar:
CREATE FUNCTION FunPers_Nombre (@ParamEmtrada1 int, @ParamEmtrada2 bit, ...)
RETURNS int
AS
BEGIN
declare @ret int
-- codigo
RETURN @ret
END
-- llamada a la funcion
SELECT dbo.FunPers_Nombre (ValorParamEmtrada1, ValorParamEmtrada2, ...)
Sintaxis de una función de tipo tabla:
CREATE FUNCTION FunPers_Nombre (@ParamEmtrada1 int, @ParamEmtrada2 bit, ...)
RETURNS @Tab_ret TABLE (Column1 int, Column2 smallint, ...)
AS
BEGIN
-- rellenar tabla retorno
-- retorno
RETURN
END
go
-- llamada a la funcion
SELECT * FROM dbo.FunPers_Nombre (ValorParamEmtrada1, ValorParamEmtrada2, ...)
Sintaxis de una función in-line:
CREATE FUNCTION FunPers_Nombre (@ParamEmtrada1 int, @ParamEmtrada2 bit, ...)
RETURNS TABLE AS RETURN
(
-- consulta a ejecutar
)
go
-- llamada a la funcion
SELECT * FROM dbo.FunPers_Nombre (ValorParamEmtrada1, ValorParamEmtrada2, ...)
Las funciones escalares son las más ineficientes, es importante usar siempre que se pueda funciones in-line, ya que permite trabajar con ellas como si fuesen tablas o vistas (ver ejemplo función in-line de cálculo de totales).
Ejemplo: Transformar el procedimiento almacenado del ejercicio anterior y crear función escalar para devolver el total de una factura pasada por parámetro.
CREATE FUNCTION FunPersDatosFactura (@IdFactura T_Id_Factura)
RETURNS T_Decimal
AS
BEGIN
DECLARE @ret T_Decimal
-- codigo
SELECT @ret=SUM(TotalBaseEuros)
FROM Facturas_Cli_Cab F INNER JOIN Facturas_Cli_Totales_Bases B ON F.IdFactura=B.IdFactura
WHERE F.IdFactura=@IdFactura
-- retorno
RETURN @ret
END
Ejemplo: Transformar el procedimiento almacenado del ejercicio anterior y crear función de tipo tabla que realice la misma función.
CREATE FUNCTION FunPersDatosFactura (@IdFactura T_Id_Factura)
RETURNS @Tab_Ret TABLE (Anyo int, ImporteEuros T_Decimal)
AS
BEGIN
-- rellenar tabla retorno
INSERT INTO @Tab_Ret (Anyo, ImporteEuros)
SELECT YEAR(F.FechaFact),SUM(TotalBaseEuros)
FROM Facturas_Cli_Cab F INNER JOIN Facturas_Cli_Totales_Bases B ON F.IdFactura=B.IdFactura
WHERE F.IdFactura=@IdFactura
GROUP BY F.FechaFact
-- retorno
RETURN
END
Ejemplo: Transformar la función de tipo tabla del ejercicio anterior en una función in-line.
CREATE FUNCTION FunPersDatosFactura3 (@IdFactura T_Id_Factura)
RETURNS TABLE AS RETURN
(
-- rellenar tabla retorno
SELECT YEAR(F.FechaFact) Anyo,SUM(TotalBaseEuros) Total
FROM Facturas_Cli_Cab F INNER JOIN Facturas_Cli_Totales_Bases B ON F.IdFactura=B.IdFactura
WHERE F.IdFactura=@IdFactura
GROUP BY F.FechaFact
)
Al igual que en los procedimientos en las funciones también es posible escribir código personalizado dentro de los objetos preparados para ello. Pero al contrario que en los procedimientos si se personaliza una función no se pueden mostrar resultados de la ejecución del código de la función estándar, con esta consulta podemos ver todos los procedimientos personalizables:
select name,* from actualizador_objetos where noactualizar=1 and xtype in ('FN','IF','TF') order by 1
Conoce más sobre transact SQL consultado todo el material que tenemos publicado aquí