En SQL Server, puede crear una función escalar definida por el usuario usando CREATE FUNCTION
declaración. Una función escalar definida por el usuario, también conocida como UDF escalar, es una función definida por el usuario que devuelve un único valor.
Este artículo contiene ejemplos de cómo crear algunas UDF escalares de T-SQL básicas.
Sintaxis
Primero, veamos la sintaxis para crear UDF escalares.
La sintaxis de las UDF escalares de T-SQL es la siguiente:
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ][ type_schema_name. ] parameter_data_type [ = default ] [ READONLY ] } [ ,...n ] ] ) RETURNS return_data_type [ WITH <function_option> [ ,...n ] ] [ AS ] BEGIN function_body RETURN scalar_expression END [ ; ]
Y la sintaxis para las UDF escalares de CLR:
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name ( { @parameter_name [AS] [ type_schema_name. ] parameter_data_type [ = default ] } [ ,...n ] ) RETURNS { return_data_type } [ WITH <clr_function_option> [ ,...n ] ] [ AS ] EXTERNAL NAME[ ; ]
Las partes en <function_option>
para funciones T-SQL y <clr_function_option>
para las funciones CLR le permiten especificar opciones para la UDF. Las opciones de función incluyen agregar cifrado, enlace de esquema, un EXECUTE AS
cláusula, además de especificar qué hacer cuando se pasa un valor NULL como argumento.
Puede encontrar una lista completa de argumentos y opciones de funciones en el sitio web de Microsoft.
La documentación de Microsoft contiene muchos detalles, por lo que los siguientes ejemplos tienen como objetivo proporcionar una descripción general rápida de algunos conceptos y opciones comunes al crear UDF escalares.
Ejemplo 1:UDF escalar básico
Este es un ejemplo del código utilizado para crear una UDF escalar T-SQL básica.
CREATE FUNCTION dbo.ufn_discountPrice( @price DECIMAL(12,2), @discount DECIMAL(12,2) ) RETURNS DECIMAL (12,2) AS BEGIN RETURN @price * (1 - @discount); END;
Esta UDF escalar acepta dos parámetros; @price
y @discount
. Estos se pasan a la función como argumentos cada vez que se invoca la función. La función toma el valor de esos argumentos, realiza un cálculo usando esos valores y luego devuelve el valor resultante. En este caso, se devuelve el precio con descuento.
Ejemplo 2:invocar la UDF
Una vez que se ha creado el UDF, se puede invocar dentro del código T-SQL en cualquier momento que lo necesite.
Este es un ejemplo de cómo invocar la UDF:
SELECT dbo.ufn_discountPrice(100, .2) AS Result;
Resultado
+----------+ | Result | |----------| | 80.00 | +----------+
Ejemplo 3:consulta de una tabla
Las UDF escalares también pueden hacer cosas como consultar tablas de bases de datos.
Aquí hay uno que devuelve la cantidad de álbumes que hay en la base de datos para un artista determinado.
CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int) RETURNS smallint AS BEGIN DECLARE @AlbumCount int; SELECT @AlbumCount = COUNT(AlbumId) FROM Albums WHERE ArtistId = @ArtistId; RETURN @AlbumCount; END;
Esta es una función escalar porque devuelve un solo valor. Si quisiéramos devolver una lista de álbumes, necesitaríamos usar una función con valores de tabla, porque las funciones con valores de tabla devuelven sus resultados como un conjunto de filas.
Ejemplo 4:enlace de esquema
Cuando crea una función definida por el usuario que depende de otros objetos en la base de datos, generalmente es una buena idea vincular el esquema a la UDF. El enlace de esquema de la UDF garantiza que no se puedan realizar cambios en los objetos subyacentes que podrían afectar potencialmente a la función.
Por ejemplo, no podría descartar una tabla que utiliza un UDF vinculado a un esquema en su definición.
Para vincular un esquema a una UDF, use WITH SCHEMABINDING
en su definición. También debe usar nombres de dos partes para cualquier objeto al que se haga referencia en la UDF.
Aquí está el ejemplo anterior reescrito para que esté vinculado al esquema:
CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int) RETURNS smallint WITH SCHEMABINDING AS BEGIN DECLARE @AlbumCount int; SELECT @AlbumCount = COUNT(AlbumId) FROM dbo.Albums WHERE ArtistId = @ArtistId; RETURN @AlbumCount; END;
Entonces, cambié dos cosas del primer ejemplo. Agregué WITH SCHEMABINDING
y cambié Albums
a dbo.Albums
.
Ahora, si alguien intenta eliminar esa tabla o realizar otros cambios en ella, obtendrá un error.
Ejemplo 5:Cifrado
También puede usar WITH ENCRYPTION
para cifrar la función.
CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int) RETURNS smallint WITH ENCRYPTION AS BEGIN DECLARE @AlbumCount int; SELECT @AlbumCount = COUNT(AlbumId) FROM dbo.Albums WHERE ArtistId = @ArtistId; RETURN @AlbumCount; END;
Ejemplo 6:entrada NULL
Al invocar la función, si alguno de los argumentos es NULL, el cuerpo de la función aún se ejecuta. Es decir, a menos que haya indicado explícitamente RETURNS NULL ON NULL INPUT
en la definición de la función.
Especificar esa opción devolverá NULL si alguno de los argumentos es NULL.
CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int) RETURNS smallint WITH RETURNS NULL ON NULL INPUT AS BEGIN DECLARE @AlbumCount int; SELECT @AlbumCount = COUNT(AlbumId) FROM dbo.Albums WHERE ArtistId = @ArtistId; RETURN @AlbumCount; END;
Cuando invoco la función usando NULL como argumento:
SELECT dbo.ufn_CountAlbums(NULL) AS Result;
Obtengo un resultado diferente, dependiendo de lo que haya especificado para esta opción.
Aquí está el resultado cuando la función usa la configuración predeterminada (CALLED ON NULL INPUT
):
+----------+ | Result | |----------| | 0 | +----------+
Y aquí está el resultado cuando usa RETURNS NULL ON NULL INPUT
:
+----------+ | Result | |----------| | NULL | +----------+
Ejemplo 7:múltiples opciones
Puede separar varias opciones con una coma.
Aquí hay un ejemplo que agrega cifrado y enlace de esquema a la función:
CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int) RETURNS smallint WITH ENCRYPTION, SCHEMABINDING AS BEGIN DECLARE @AlbumCount int; SELECT @AlbumCount = COUNT(AlbumId) FROM dbo.Albums WHERE ArtistId = @ArtistId; RETURN @AlbumCount; END;
Ejemplo 8:modificar una función
Puede modificar una UDF escalar reemplazando CREATE
con ALTER
.
ALTER FUNCTION dbo.ufn_CountAlbums (@ArtistId int) RETURNS smallint WITH SCHEMABINDING AS BEGIN DECLARE @AlbumCount int; SELECT @AlbumCount = COUNT(AlbumId) FROM dbo.Albums WHERE ArtistId = @ArtistId; RETURN @AlbumCount; END;